Kubernetes

23.9.1(금) 쿠버네티스 6일차

사실 나도 모름 2023. 9. 1. 16:53

job은 리눅스의 크론데몬과 비슷한 형태로 컨테이너의 작업예약 및 실행주기에 관여한다.

 

https://kubernetes.io/ko/docs/concepts/workloads/controllers/job/

 

잡에서 하나 이상의 파드를 생성하고 지정된 수의 파드가 성공적으로 종료될 때까지 계속해서 파드의 실행을 재시도한다. 파드가 성공적으로 완료되면, 성공적으로 완료된 잡을 추적한다. 지정

kubernetes.io

 

apiVersion: batch/v1
kind: Job
metadata:
  name: job-example
spec:
  completions: 6
  parallelism: 3
  activeDeadlineSeconds: 15 	# 15초 내로 시작하지 않으면 강제로 종료해라
  template:
    spec:
      containers:
      - name: centos-container
        image: centos:7
        command: ["bash"]
        args:
        - "-c" 	# 커맨드로 읽어라 -> man bash 참조
        - "echo 'Hello world' ; sleep 50 ; echo 'Bye' " # 커맨드 명령어 Hello world 출력 후 50초 쉬고 Bye출력
      restartPolicy: Never
      restartPolicy: OnFailure
  backoffLimit: 6

15초를 주면 3개의 실패 3개의 성공이 나온다.

위의 실습을 통해서 알 수 있는 것이 컨테이너를 생성할 때 sleep 5를 줌으로 지연이 생기고

activeDeadlineSeconds: 15 로 인해 6개의 컨테이너가 실행되기에 시간이 충분치 않으므로 중간에 실패가 생기게 된다.

모두 실행되는데 18초가 소요되는데 30초가 아니라 왜 18초인지는 아직 이해가 잘 안된다.

느낌은 Parallelism: 3 이 원인이지 싶다.

 

 


Job

관리자의 개입없이 자동으로 특정한 작업을 수행하기 위한 명령

crontab -e 편집

crontab -l 화면 출력

crontab -r 설정한 job 삭제

cat<<EOF>nginx-cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: cronjob-example
spec:
  schedule: "*/2 * * * *"
  startingDeadlineSeconds: 60
  concurrencyPolicy: Allow
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: nginx-container
            image: nginx:1.14
            command: ["bash"]
            args:
            - "-c"
            - "echo 'Hello world' ; sleep 30 "
          restartPolicy: Never
EOF

 

 


Service

https://kubernetes.io/ko/docs/concepts/services-networking/service/

 

서비스

외부와 접하는 단일 엔드포인트 뒤에 있는 클러스터에서 실행되는 애플리케이션을 노출시키며, 이는 워크로드가 여러 백엔드로 나뉘어 있는 경우에도 가능하다.

kubernetes.io

쿠버네티스에서는 pod와 service가 따로다.

내부 IP를 가지고 있어 외부로 노출되지 않는 데몬을 외부에 노출된 서비스와 연결해줌으로 데몬을 외부에서 사용가능하게 만든다.

쿠버네티스는 이 서비스에 서비스 프록시가 사용하는 IP 주소 ("cluster IP"라고도 함) 를 할당한다.

 

일반적으로 셀렉터를 이용하여 pod와 연결하지만 셀렉터를 쓰지 않고도 연결할 수 있는 방법이 있다.

잘쓰이지는 않지만 EndpointSlice를 사용하여 연결이 가능하다.

 

노드포트를 이용해서 외부에서 서비스를 할 수도 있다.

노드포트란 노드의 진입점 포트로 노드포트의 IP와 Port를 명시하여 접근하면 서비스받을 수  있다.

로드밸런서도 사용이 가능하나 직접 구현하는 것은 쉽지 않다.

그래서 보통 AWS나 AZURE같은 퍼블릭 로드밸런서를 활용하여 구현한다.

 

cat <<EOF>run-my-nginx.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
spec:
  selector:
    matchLabels:
      run: my-nginx
  replicas: 2
  template:
    metadata:
      labels:
        run: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx
        ports:
        - containerPort: 80
EOF
k edit -f run-my-nginx.yaml	# 실행중인 파드정보수정
k expose deploy/my-nginx	# 적용
k get endpoints my-nginx	# endpoint 확인

기존의 웹서비스의 포트를 edit 명령으로 80에서 8080으로 수정해주고 expose해줌으로 적용

80번 포트로 접속 가능하던 웹서비스가 8080으로 접속이 가능해진다.

하지만 컨테이너 내부에서 80포트만 열려있는 관계로 접속이 불가능했다.

 

cat<<EOF>dep-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dep-nginx
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14
        ports:
        - containerPort: 80
EOF
cat<<EOF>svc-nginx.yaml
apiVersion: v1
kind: Service
metadata:
  name: ser-nginx
spec:
  clusterIP: 10.99.0.1
  selector:
    app: nginx #동일 App Label Pods
  ports:
  - protocol: TCP
    port: 80 #cluster Port
    targetPort: 80 #container Port
EOF

service 정보를 확인할 때 endpoint가 정상적으로 3개가 모두 올라왔는지 확인한다.

 

 

 


노드포트

cat<<EOF>svc-nginx.yaml
apiVersion: v1
kind: Service
metadata:
  name: ser-nginx
spec:
  clusterIP: 10.99.0.1
  selector:
    app: nginx #동일 App Label Pods
  ports:
  - protocol: TCP
    port: 80 #cluster Port
    targetPort: 80 #container Port
EOF
cat<<EOF>service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
  name: service-nodeport
  labels:
    app: nginx
spec:
  type: NodePort
  clusterIP: 10.99.0.1
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 32000 # 생략 가능
EOF

service를 통해 포트를 32000번으로 고정을 시킴으로 컨테이너로 접근할 때 외부에서 32000번으로 접속해야 컨테이너에 접근이 가능해진다.

대충 이런 느낌의 포트포워딩?

위와 같은 service를 통해 외부에서 접속하는 사용자는 서비스의 32000번 포트로 접근하면 실제로 컨테이너로 웹 서비스를 직접 접근하는 것과 같은 효과를 보게 된다.

 

 

 


로드밸런서

cat<<EOF>service-lb.yaml
apiVersion: v1
kind: Service
metadata:
  name: service-loadbalancer
  labels:
    app: nginx
spec:
  type: LoadBalancer
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
EOF

위 서비스를 실행하더라도 동작하지 않는다.

이유는 모른다.

 

Bare Metal 클러스터용 load balancer metallb 설치 과정

https://mlops-for-all.github.io/docs/appendix/metallb/

 

2. Bare Metal 클러스터용 load balancer metallb 설치 | MLOps for ALL

MetalLB란?

mlops-for-all.github.io

mkdir ~/lb
cd lb

kubectl get configmap kube-proxy -n kube-system -o yaml | grep strictARP

kubectl get configmap kube-proxy -n kube-system -o yaml | sed -e "s/strictARP: false/strictARP: true/" | kubectl apply -f - -n kube-system

kubectl apply \
-f https://raw.githubusercontent.com/metallb/metallb/v0.11.0/manifests/namespace.yaml

wget https://raw.githubusercontent.com/metallb/metallb/v0.11.0/manifests/namespace.yaml

wget https://raw.githubusercontent.com/metallb/metallb/v0.11.0/manifests/metallb.yaml

kubectl get pod -n metallb-system
cat <<EOF > metallb_config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.168.108.100-192.168.108.110  # IP 대역폭
EOF

kubectl apply -f metallb_config.yaml
cat<<EOF > lb.yaml
apiVersion: v1
kind: Service
metadata:
  name: service-loadbalancer
  labels:
    app: metallb
  namespace: metallb-system
spec:
  type: LoadBalancer
  selector:
    app: metallb
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
EOF

kubectl apply -f lb.yaml
cat <<EOF > dep-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dep-nginx
  labels:
    app: metallb
  namespace: metallb-system
spec:
  replicas: 3
  selector:
    matchLabels:
      app: metallb
  template:
    metadata:
      name: dep-nginx
      labels:
        app: metallb
    spec:
      containers:
      - name: nginx
        image: nginx:1.14
EOF

kubectl apply -f dep-nginx.yaml
k get pods,svc,deploy -o wide -n metallb-system

EXTERNAL-IP인 192.168.108.101로 접속했을 때 위 화면이 뜨면 성공이다.

 

'Kubernetes' 카테고리의 다른 글

23.9.6(수) 쿠버네티스 8일차  (0) 2023.09.06
23.9.4(월) 쿠버네티스 7일차  (0) 2023.09.04
23.8.25(금) 쿠버네티스 1일차  (0) 2023.09.01
23.8.28(월) 쿠버네티스 2일차  (0) 2023.09.01
23.8.29(화) 쿠버네티스 3일차  (0) 2023.09.01