PLCnext에서 클러스터 관리: Kubernetes로 산업 자동화 활용하기
IT 분야에서 수년간 표준이었지만, 산업 분야에서는 아직 큰 영향을 미치지 못했습니다. 종종 이러한 기술은 너무 복잡하고 불필요하다고 여겨집니다. 드는 질문은, 이들이 우리에게 이점을 가져다주는가입니다.
Kubernetes를 예로 들어 PLCnext에 대한 비전.
Kubernetes
Kubernetes는 컨테이너를 사용하여 다양한 장치를 통해 네트워크를 형성하는 오케스트레이터(관리 시스템, 마스터)입니다. 이 시스템은 애플리케이션을 약간 다른 방식으로 제공하는 데 사용됩니다.
전통적으로 애플리케이션은 장치에 분산되어 유지관리됩니다. 애플리케이션이 어떤 컴퓨터에서 실행되는지 알려져 있습니다. 애플리케이션이 다른 컴퓨터에서 실행되어야 한다면 사람이 해야 합니다. 컴퓨터 중 하나가 실패하면 해당 컴퓨터의 모든 애플리케이션을 더 이상 사용할 수 없습니다.
Kubernetes에서는 마스터에게 애플리케이션의 상태 설명이 주어지고, 마스터가 나머지를 처리합니다. 요청된 상태가 항상 유지되도록 보장합니다. 그러나 애플리케이션이 현재 어떤 노드에서 실행 중인지는 알 수 없지만, 원칙적으로 접근 가능합니다.
질문과 답변
상태 설명이란 무엇인가
- 상태 설명은 모든 애플리케이션의 기초입니다. 예를 들어 어떤 컨테이너를 어떤 버전으로 사용할지, 로드 밸런싱을 위해 애플리케이션을 여러 번 시작해야 하는지 등을 포함합니다. 완전히 텍스트 형태로
json 또는 yaml 파일로 작성됩니다. 따라서 완전히 버전 관리 가능합니다(예: Git 또는 SVN).
클러스터 설치 방법
- 참여자(마스터와 노드)에 두 소프트웨어 구성 요소(컨테이너 런타임과 Kubernetes)를 제공해야 합니다. 그 후 토큰을 통한 마스터 로그인 한 번만 필요합니다. 나머지는 마스터가 처리합니다.
애플리케이션 업데이트 수행 방법
- 업데이트는 단순히 애플리케이션의 상태 설명을 새 것으로 교체하는 것입니다. 업데이트는 실시간으로 수행됩니다. 즉, 새 애플리케이션이 먼저 설치되고 시작되며 마지막 순간에 이전 애플리케이션이 종료됩니다. 업데이트가 실패하면 롤백을 실행하여 이전 상태를 간단히 복원할 수 있습니다. 오케스트레이터는 모든 이전 상태를 유지합니다. 또한 설명된 상태의 버전 관리 가능성이 존재합니다.
- 새로운 업데이트 시나리오가 여기서 발생합니다. 애플리케이션이 클러스터에서 자주 실행되는 경우, 예를 들어 애플리케이션의 일부만 먼저 업데이트할 수 있습니다. 며칠 또는 몇 주 테스트 후 오류가 없으면 나머지를 업데이트할 수 있습니다.
노드가 실패하면 어떻게 되는가
- 어느 시점에서 노드가 실패하면 모든 애플리케이션이 단순히 다른 노드에서 사용 가능해집니다. 접근성은 동일하게 유지됩니다. 충분한 컴퓨팅 파워가 있는 한 모든 애플리케이션을 계속 실행할 수 있습니다. 장애 시 많은 문제를 일으키는 중앙 구성 요소인 MQTT 서버에 대해 많은 논의가 있지만, 클러스터에서는 문제가 되지 않습니다.
마스터가 실패하면 어떻게 되는가
- 마스터도 중복 실행할 수 있습니다. 하나가 실패하면 다른 노드가 작업을 인계할 수 있습니다.
특정 애플리케이션이 하드웨어 접근 때문에 특정 노드에서 실행되어야 한다
- 이는 상태 설명에 포함될 수 있습니다. 상태는 장치에 속한 태그를 기반으로 할당될 수도 있습니다. 예: 각 AXCF2152는 특정 애플리케이션을 실행해야 합니다. MQTT 예시를 다시 들면, 연합에서 실행되는 MQTT 서버가 있고, 각 노드는 MQTT 클라이언트를 장착하여 MQTT 서버와 통신을 설정할 수 있습니다. 마스터는 한 번만 존재하고, 클라이언트는 각 노드에서 실행됩니다.
예제
프론트엔드, 백엔드, 데이터베이스 세 개의 컨테이너로 구성된 애플리케이션의 상태 설명 예제.
배포:
서비스:
- 클러스터 중앙에서 애플리케이션 인터페이스 생성. 배포가 어느 노드에서 실행되든 인터페이스는 항상 유효함.
인그레스:
- DNS 항목을 사용하여 인터페이스를 프론트엔드에 연결. 따라서 프론트엔드는 항상 한 도메인에서 접근 가능.
- Proxy
https://MyApp.MyDomain.de/를 프론트엔드 서비스(포트 80)로
- Proxy
https://MyApp.MyDomain.de/api를 백엔드 서비스(포트 3000)로
# 배포 종류
kind: Deployment
apiVersion: apps/v1
metadata:
name: MyApplicationName
labels:
app: MyApplication
MyApplication: MyApplicationName
namespace: default
## 컨테이너 사양
spec:
containers:
## 프론트엔드 컨테이너 사양
## 컨테이너 이름
- name: MyContainer-frontend
## 사용할 컨테이너 이미지
image: MyApplicationImage_frontend
## 프론트엔드 포트, http
ports:
- containerPort: 80
## 백엔드 컨테이너 사양
- name: MyContainerName-backend
image: MyApplicationImage_backend
ports:
- containerPort: 3000
## MongoDB 컨테이너 사양
- name: MyContainerName-mongo
image: mongo:3.4
## Mongo DB 시작 명령
command:
- "mongod"
- "--bind_ip"
- "0.0.0.0"
ports:
- containerPort: 27017
---
## 서비스 선언, 포트를 쿠버네티스 API에 노출(내부만 접근 가능)
apiVersion: v1
kind: Service
metadata:
name: MyApplicationName
spec:
ports:
- name: frontend
targetPort: 80
port: 80
- name: backend
targetPort: 3000
port: 3000
selector:
app: MyApplication
task: MyApplicationName
---
## 인그레스 선언, 프록시를 프론트엔드와 백엔드에 바인딩
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
## 인그레스를 traefik 서비스 프록시에 바인딩
metadata:
name: MyApplicationName
annotations:
kubernetes.io/ingress.class: traefik
## 프론트엔드 인그레스 클래스, DNS 인그레스를 서비스 포트 80에 매핑
spec:
rules:
- host: MyApp.Mydomain.de
http:
paths:
- path: /
backend:
serviceName: MyApplicationName
servicePort: frontend
## 백엔드 인그레스 클래스, DNS 인그레스를 서비스 포트 3000에 매핑
- host: MyApplicationName.MyDomain.de
http:
paths:
- path: /api
backend:
serviceName: MyApplicationName
servicePort: backend
참고 자료
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/
https://github.com/k3s-io/k3s
https://github.com/rancher/k3d
https://github.com/inercia/k3x