본문 바로가기
DevOps/Kubernates

[CAK] 36-48 Sevice, Namespace, Kubectl commands

by BenKangKang 2023. 3. 30.

Certified Kubernetes Administrator (CKA) with Practice Tests 정리 내용입니다.

36. Service

  • 서비스는 다양한 컴포넌트들을 외부 앱과 통신할 수 있도록 해준다.
    • Pods 그룹 간의 연결이 가능하도록 해준다.
  • 쿠버네티스 Object
  • 줄임말은 svc

External Communication

랩톱으로 웹 서버에 접근하는 방법

쿠버네티스 노드에 있는 팟 ip는 별도의 네트워크에 있음으로 바로 접근할 수 없다.

  1. SSH 로 Node에 접근해서 curl 등의 통신을 하는 방법
  2. Service 를 사용하는 방법

1. SSH

2. Service 를 이용

  • 직접적으로 요청을 할 수 없음으로 중간에서 요청을 매핑하는데 도움이 되는 무언가가 필요하다.

Service Types

NodePort

  • port 랑 맵핑하는 것
  • 기본적으로 30,000 ~ 32,767 범위.
  • 등록되면 서비스가 노드의 포트를 수신하기 때문에 포드에 요청을 전달할 수 있다.
    • Labtop 쪽에서 http://192.168.1.2:30008 으로 요청을 보내면 이를 리스닝하는 것

apiVersion: v1
kind: Service
metadata:
 name: myapp-service
spec:
 type: NodePort
 ports:
 - targetPort: 80
   port: 80
   nodePort: 30008
 selector:
   app: myapp
   type: front-end
  • port 값만 필수다
    • nodePort 가 없으면 자동 배정된다.
    • targetPort 가 없으면 port 와 같은 값으로 설정한다.
  • 단일 서비스에서 여러 포트에 매핑할 수 있다.
  • selector 섹션을 사용해서 서비스를 포드에 연결한다.
    • labels: myapp 으로 되어 있을 거임, 오른쪽 사진이 좀 이상함.

한 노드에 matchPod이 여러개인 경우에는?

  • 같은 label 을 갖고 있는 경우 로드 밸런싱이 되며 무작위 알고리즘을 사용해서 로드 균형을 조정한다.

여러 노드에 matchPod 이 퍼져있는 경우에는?

  • 쿠버네티스가 자동으로 spans 서비스를 자동으로 생성한다.

37. ClusterIP

  • 필요한 이유 → 팟 IP에 의존할 수 없다
    • 우리가 서비스를 개발하다모녀 위와 같은 서비스 계층이 생기게 되는데, 모든 팟에는 IP가 있다
    • 하지만 IP는 정적이 아니고, 팟은 항상 다운될 수 있는 개체이다.
  • 클러스터 서비스는 Pod을 그룹화하여 액섹스할 수 있는 단일 인터페이스를 제공한다.
    • 요청은 무작위 팟으로 전달된다.
  • 각 서비스에는 IP와 이름이 할당된다. 클러스터 내부에서 사용하는 이름이다.
    • 다른 포드에서 서비스에 액세스하는데 이런 유형의 서비스를 클러스터 IP라고한다
apiVersion: v1
kind: Service
metadata:
 name: back-end
spec:
 types: ClusterIP
 ports:
 - targetPort: 80
   port: 80
 selector:
   app: myapp
   type: back-end

38. LoadBalancer

  • 외부 클라우드 플랫폼의 네이티브 로드 밸런서를 쉽게 구성하고 사용할 수 있도록 도와주는 오브젝트

로드 밸런서가 필요한 이유 → 사용자는 여러 주소를 원하지 않는다.

  • 노드포트는 4개의 노드가 있으면 4개의 ip가 만들어진다.
    • 4개의 노드에 2개의 웹이 분산되어서 팟이 배포된다고 했을 때
  • 192.168.56.70:33035, 71:33035, …

→ 단일 URL 이 필요하다.

1. nginx 프록시 등을 직접 사용하는 방법

  • 우리는 1개의 HAproxy, nginx 등을 이용해서 라우팅될 수 있도록 한다.
    • 특정 url 요청오면 node port 로 연결시키겠지

2. 만약 매니지드에서 지원하는 로드밸런서를 쓸때는?

  • 쿠버네티스 로드 밸런서 오브젝트 사용

39. Practice Test - Services


40. Solution - Service(optional)


41. Namespaces

  • 네임스페이스: 집
    • 각 집마다 성이 같은 강주영이 있을 수 있다.
  • 기본적으로는 클러스터 처음 구성 시 생성되는 default 네임스페이스를 사용한다
  • 기본 제공되는 네임 스페이스
    • default
    • kube-system
      • 네트워킹 솔루션에 필요한 DNS 서비스 들을 위한 네임스페이스
    • kube-public

네임스페이스를 만드는 이유

  • 격리된 환경에서 리소스 수정이 발생하지 않도록함

각 네임스페이스에는 고유한 정책 집합을 가질 수 있다

  • 네임스페이스에서 허용 한도 이상의 자원을 사용하지 않는다.
  • Resource Limits
    • ResourceQuota

네임스페이스 접근 방법

  • 각 네임스페이스에 db-service 가 있다고 가정했을 때
    • 같은 네임스페이스: mysql.connect(”db-service”)
    • 다른 네임스페이스: mysql.connect(”db-service.dev.svc.cluster.local”)
      • dev라는 네임스페이스의 svc 중에 클러스터 local 을 가져옴

서비스의 DNS 항목

  • 서비스 생성 시 db-service.dev.svc.cluster.local 와 같은 것이 자동으로 추가된다.
    • db-service: service name
    • dev: namespace
    • svc: 서비스
    • domain: cluster.local

네임 스페이스 접근 명령어

kubectl get pods --namespace=kube-system

네임스페이스에 할당하는 방법

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  namespace: dev
  labels:
     app: myapp
     type: front-end
spec:
  containers:
  - name: nginx-container
    image: nginx
  • metadata section 에 적으면된다.

네임스페이스 만드는 방법

apiVersion: v1
kind: Namespace
metadata:
  name: dev
  • or kubectl create namespace dev

네임스페이스 바꾸는 방법

  • 계속 바꾸려면 kubecl config set-context~~~ 설정
  • 모든 네임스페이스 보려면 --all-namespaces

42. Practice Test - Namespaces


43. Solution - Namespaces(optional)


44. Imperative(명령형, 긴급한, 피할 수 없는) vs Declarative(선언적)

  • 쿠버네티스의 명령형, 선언적 접근 방식에 대한 내용

Imperative

  • 목적보다는 절차가 중요하다
  • 각 단계마다 기존 상태 고려가 필요함

Declarative

  • 절차보다는 목적이 중요하다.
  • 무엇이 되기를 바라는 상태를 정의하면 상태나 예외 처리는 시스템이 알아서함.
  • kubectl edit 은 메모리에 있느 값만 바꾸기 때문에 어디에도 기록되지 않는다. → replace 로 대체
    • kubectl replace -f nginx.yaml kubectl replace --force -f nginx.yaml

 

명령형의 단점

  • 괸라자가 현재 상태를 외우고 있어야함.

선언형

 
 
 
 
100%
 
  • apply 를 통해서 관리

  • 명령형의 경우 시험에서는 쓰지만 실제 운영에서느 안쓰는 것이 좋음. yaml파일로 정의하자.
    • create
      • run
      • create
      • expose
    • update
      • edit
      • scale
      • set

45. Certifications Tips - Imperative Commands with Kubectl

While you would be working mostly the declarative way - using definition files, imperative commands can help in getting one time tasks done quickly, as well as generate a definition template easily. This would help save considerable amount of time during your exams.

Before we begin, familiarize with the two options that can come in handy while working with the below commands:

  • -dry-run: By default as soon as the command is run, the resource will be created. If you simply want to test your command , use the -dry-run=client option. This will not create the resource, instead, tell you whether the resource can be created and if your command is right.
  • o yaml: This will output the resource definition in YAML format on screen.

Use the above two in combination to generate a resource definition file quickly, that you can then modify and create resources as required, instead of creating the files from scratch.

POD

Create an NGINX Pod

kubectl run nginx --image=nginx

Generate POD Manifest YAML file (-o yaml). Don't create it(--dry-run)

kubectl run nginx --image=nginx --dry-run=client -o yaml

Deployment

Create a deployment

kubectl create deployment --image=nginx nginx

Generate Deployment YAML file (-o yaml). Don't create it(--dry-run)

kubectl create deployment --image=nginx nginx --dry-run=client -o yaml

Generate Deployment with 4 Replicas

kubectl create deployment nginx --image=nginx --replicas=4

You can also scale a deployment using the kubectl scale command.

kubectl scale deployment nginx --replicas=4

Another way to do this is to save the YAML definition to a file and modify

kubectl create deployment nginx --image=nginx --dry-run=client -o yaml > nginx-deployment.yaml

You can then update the YAML file with the replicas or any other field before creating the deployment.

Service

Create a Service named redis-service of type ClusterIP to expose pod redis on port 6379

kubectl expose pod redis --port=6379 --name redis-service --dry-run=client -o yaml

(This will automatically use the pod's labels as selectors)

Or

kubectl create service clusterip redis --tcp=6379:6379 --dry-run=client -o yaml (This will not use the pods labels as selectors, instead it will assume selectors as app=redis. You cannot pass in selectors as an option. So it does not work very well if your pod has a different label set. So generate the file and modify the selectors before creating the service)

Create a Service named nginx of type NodePort to expose pod nginx's port 80 on port 30080 on the nodes:

kubectl expose pod nginx --type=NodePort --port=80 --name=nginx-service --dry-run=client -o yaml

(This will automatically use the pod's labels as selectors, but you cannot specify the node port. You have to generate a definition file and then add the node port in manually before creating the service with the pod.)

Or

kubectl create service nodeport nginx --tcp=80:80 --node-port=30080 --dry-run=client -o yaml

(This will not use the pods labels as selectors)

Both the above commands have their own challenges. While one of it cannot accept a selector the other cannot accept a node port. I would recommend going with the kubectl expose command. If you need to specify a node port, generate a definition file using the same command and manually input the nodeport before creating the service.


46. Practice Test - Imperative Commands

NOTE: Please remember to use Google Chrome for opening the Quiz Portal. On other browsers it sometime freezes.

Practice Test Link: https://uklabs.kodekloud.com/topic/practice-test-imperative-commands-3/


47. Solution - Imperative Commands (Optional)


48. Kubectl Apply Command

  • local file
  • last applied configuration
    • apply 이후 json 으로 저장되며 항상 클러스터 라이브 configuration 에 json string 으로 저장되어 있다.
    • apply 하면 local file과 last applied configuration 를 비교한다
      • 즉 명령형, 선언형 서로 혼합해서 사용하지 마라
  • kubernetes
  •  

댓글