Ubuntu 22.04 에서 CRI-O, Kubernetes 1.28 Cluster, Calico 설치 및 애플리케이션 배포

반응형

Kubernetes 는 컨테이너의 생성, 배포, 실행을 하는 등 컨테이너를 관리하는 오픈소스 플랫폼 입니다.

여기에서는 Ubuntu 22.04 버전의 서버 3대로 (master 노드 1대 / worker 노드 2대) Kubernetes 1.28 을 구성하는 방법에 대해 설명합니다.

- 공식 Documents : https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/

 

 

1. CRI-O 설치

 

CRI-O 공식 홈페이지 : https://cri-o.io

 

Pod 를 실행하고 관리할 수 있도록 Containerd 나 CRI-O 와 같은 컨테이너 런타임을 설치해야 합니다.

여기에서는 CRI-O 를 설치하도록 하겠습니다.

 

(모든 노드에서)

서버별로 호스트네임을 설정하고 각 노드에 호스트명으로 통신 가능하도록 hosts 파일에 추가합니다.

# hostnamectl set-hostname master      // master 노드에서

# hostnamectl set-hostname worker1    // worker1 노드에서

# hostnamectl set-hostname worker2    // worker2 노드에서

# vi /etc/hosts

127.0.0.1 localhost
10.101.0.5 master
10.101.0.10 worker1
10.101.0.12 worker2

 

CRI-O 는 설치할 Kubernetes 버전과 동일한 버전으로 설치합니다.

(모든 노드에서)

# OS=xUbuntu_22.04
# VERSION=1.28

 

# echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
# echo "deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.list

# curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/Release.key | apt-key add -
# curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/Release.key | apt-key add -

# apt -y update

# apt -y upgrade    // 설치중 묻는 질문에 기본값으로 답변

# apt -y install cri-o cri-o-runc cri-tools    // 설치중 묻는 질문에 기본값으로 답변

# systemctl enable --now crio

 

설치를 잘 마쳤으면 CRI-O 버전이 확인됩니다.

# crio version
crio version 1.28.0
Version:        1.28.0
GitCommit:      unknown
GitCommitDate:  unknown
GitTreeState:   clean
BuildDate:      2023-08-28T05:59:01Z
GoVersion:      go1.19
Compiler:       gc
Platform:       linux/amd64
Linkmode:       dynamic

...

 

 

2. Kubernetes 설치

 

Kubernetes 공식 홈페이지 : https://kubernetes.io

 

(모든 노드에서)

kubelet 사용을 위해 swap 을 반드시 비활성화 시켜줍니다.

# swapoff -a

# cat /etc/fstab

fstab 에서도 swap 파티션이 존재한다면 주석처리하여 비활성화 시킵니다.

 

이제 kubeadm, kubelet, kubectl 를 설치해야 하는데, 이 세가지는 모두 Kubernetes 클러스터 관리와 상호 작용을 위한 도구입니다.
- kubeadm : 클러스터를 부트스트랩하는 명령
- kubelet : 클러스터의 모든 노드에서 실행되는 POD와 컨테이너 시작과 같은 작업을 수행하는 컴포넌트
- kubectl : 클러스터와 통신하기 위한 CLI 유틸리티

 

패키지 저장소에서 파일을 안전하게 다운로드 받기 위해 아래 패키지를 설치합니다.

# apt -y install apt-transport-https ca-certificates

 

현재 기준 Kubernetes 최신 버전인 1.28 버전의 공용 서명 키를 다운로드합니다.

# curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

 

Kubernetes Repository 를 추가합니다.

# echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

 

APT 패키지 인덱스를 업데이트하고 kubelet, kubeadm, kubectl 을 설치합니다.

그리고 패키지가 자동으로 버전업 되지 않도록 고정합니다.

# apt -y update
# apt -y install kubelet kubeadm kubectl    // 설치중 묻는 질문에 기본값으로 답변
# apt-mark hold kubelet kubeadm kubectl

 

커널에 필요한 모듈을 로드 합니다.

(모든 노드에서)

# modprobe overlay
# modprobe br_netfilter

# cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

 

sysctl 파라메타 값을 설정하고 리부팅 없이 적용합니다.
# cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
# sysctl --system

 

CRI-O는 기본적으로 systemd 라는 cgroup 드라이버를 사용합니다. 

(모든 노드에서)

# cat <<EOF | sudo tee /etc/crio/crio.conf.d/02-cgroup-manager.conf
[crio.runtime]
conmon_cgroup = "pod"
cgroup_manager = "systemd"
EOF

 

 

3. Cluster 생성

 

서버간 통신할 사설 네트워크 대역을 설정합니다.

현재 노드와 중복되지 않도록 새로운 대역으로 설정해 주었습니다.

- Nodes network : 10.101.0.0/24

- Pods network : 10.101.1.0/24

쿠버네티스 구성에 필요한 이미지를 다운로드 받아야 하므로 이 단계에서 시간이 약간 소요됩니다.

(master 노드에서)

# kubeadm init --pod-network-cidr=10.101.1.0/24

 

아래는 쿠버네티스 컨트롤 플레인이 성공적으로 초기화 되었을때 출력하는 메세지 입니다.

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 10.101.0.5:6443 --token w6ioaq.l37qcxuvs98q4n02 \
--discovery-token-ca-cert-hash sha256:bddfcfabe16f76edbb6a8af08a835ebf9defc67d902dd02091174e1bccacaa76

 

위에 나와있는 안내 대로 추가 명령을 실행하는데, 현재는 root 상태이므로 아래명령으로 Kubernetes 사용자 환경을 로드 합니다.

일반 사용자 상태로 진행을 원할 경우 위 안내된 mkdir 부분부터 세줄 명령을 실행하면 됩니다.

(master 노드에서)
# export KUBECONFIG=/etc/kubernetes/admin.conf

 

앞으로 SSH 접속시마다 자동으로 환경이 로드 되도록 하면 편리합니다.

# echo 'export KUBECONFIG="/etc/kubernetes/admin.conf"' >> ~/.bashrc

 

master 노드에서 확인 가능한 노드 상태를 출력합니다.

# kubectl get nodes
NAME     STATUS   ROLES           AGE   VERSION
master   Ready    control-plane   39s   v1.28.1

 

worker 노드에서는 아래와 같이 master 서버에 join (가입) 합니다.

token 과 hash 값은 쿠버네티스 컨트롤 플레인이 초기화 되었을때 출력된 값으로 합니다.

 

(모든 worker 노드에서)

# kubeadm join 10.101.0.5:6443 --token w6ioaq.l37qcxuvs98q4n02 \
--discovery-token-ca-cert-hash sha256:bddfcfabe16f76edbb6a8af08a835ebf9defc67d902dd02091174e1bccacaa76

 

다시 master 노드에서 확인 가능한 노드 상태를 출력하면 가입된 worker 노드 리스트까지 확인이 됩니다.

ROLES 부분이 아래와 같이 출력 되었는지 확인합니다.

(master 노드에서)

# kubectl get nodes
NAME      STATUS   ROLES           AGE     VERSION
master    Ready    control-plane   2m24s   v1.28.1
worker1   Ready    <none>          88s     v1.28.1
worker2   Ready    <none>          81s     v1.28.1

 

 

[참고 : Cluster 삭제]

 

이번에는 Cluster 를 삭제하는 방법을 안내합니다.

계속 Cluster 구성 진행을 원하시는 분은 이 부분을 건너뛰면 되고, 구성이 꼬이거나 처음부터 다시 하실 분만 참고하시면 됩니다.

 

(master 노드에서)

# kubeadm reset

# rm -r /etc/cni/net.d/*
# systemctl restart kubelet

 

(모든 worker 노드에서)

kubeadm join 명령을 하기 전에 아래 명령으로 기존 Cluster 정보를 삭제해야 합니다.

# kubeadm reset

# rm -rf /etc/kubernetes/*

# systemctl stop kubelet

 

 

4. Calico 설치

 

Calico 공식 홈페이지 : https://www.tigera.io/project-calico

 

Project Calico 는 Kubernetes에 대한 네트워크 정책 엔진입니다.
Calico 네트워크 정책 집행을 통해 네트워크 세분화 및 테넌트 격리를 구현할 수 있습니다.

 

1) Calico 설치하기

(master 노드에서)

Tigera Calico 연산자 및 사용자 지정 리소스 정의를 설치합니다.

현재 기준 Calico 최신버전은 3.26.1 입니다.
# kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/tigera-operator.yaml

필요한 커스텀 리소스를 생성하여 Calico 를 설치합니다.

배포하는 yaml 파일에서 CIDR 정보를 자신이 사용하는 네트워크 정보로 수정하고 생성합니다.

# wget https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/custom-resources.yaml

# sed -i 's/192.168.0.0\/16/10.101.1.0\/24/' custom-resources.yaml 

# kubectl create -f custom-resources.yaml

다음 명령을 사용하여 모든 Pod 가 실행 중인지 확인합니다.

이 부분에서 모든 STATUS 값이 Running 이 되기까지 약간의 시간이 소요됩니다.

# kubectl get pods -n calico-system
NAME                                       READY   STATUS    RESTARTS   AGE
calico-kube-controllers-7fd8984cb7-b5t6n   1/1     Running   0          2m37s
calico-node-74bjg                          1/1     Running   0          2m37s
calico-node-8mrfw                          1/1     Running   0          2m37s
calico-node-9xn6h                          1/1     Running   0          2m37s
calico-typha-d4c4b7984-l4p5j               1/1     Running   0          2m37s
calico-typha-d4c4b7984-lc9hm               1/1     Running   0          2m31s
csi-node-driver-9lmnz                      2/2     Running   0          2m37s
csi-node-driver-hzt8h                      2/2     Running   0          2m37s
csi-node-driver-ljsds                      2/2     Running   0          2m37s

 

 

5. 애플리케이션 배포

 

볼륨을 포함한 애플리케이션을 배포하고 외부에서 접근하기 위한 네트워크 설정 및 도메인 연결 예제입니다.

 

1) Namespace

애플리케이션을 생성하고 배포할 작업공간을 생성하고 현재의 공간으로 변경해줍니다.

(master 노드에서)

# kubectl create ns sysdocu

# kubectl config set-context --current --namespace=sysdocu

 

2) Volume 생성

NFS, GlusterFS, Ceph 등 별도의 서버를 미리 구성하고 해당 공간을 할당받기 위해

PV (Persistent Volume) 와 PVC (Persistent Volume Claim) 를 생성하는 방법도 있지만,

여기에서는 Pod 가 배포된 worker 노드의 공간을 할애하는 hostPath 방법으로 진행해 보겠습니다.

hostPath 를 사용할 경우 디렉토리를 지정하는 것 외에 별도 작업은 없습니다.

html 데이터를 저장할 디렉토리를 생성합니다.

(모든 worker 노드에서)

# mkdir /html

 

3) Deployment 생성

Deployment 를 사용하면 Pod 생성 및 여러가지 옵션을 추가하여 다양한 구성이 가능합니다.

Deployment yaml 파일을 작성합니다.

(master 노드에서)

# vi deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - containerPort: 80
          volumeMounts:
            - name: html-volume
              mountPath: /html/user001
      volumes:
        - name: html-volume
          hostPath:
            path: /usr/share/nginx/html
            type: DirectoryOrCreate

 

작성한 yaml 파일을 적용하여 생성합니다.

# kubectl apply -f deployment.yaml

deployment.apps/nginx-deployment created

 

Pod 가 자동 생성되는데, 아래와 같이 확인이 가능합니다.

# kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-694db9fb84-b5h2r   1/1     Running   0          20s

 

4) Service 생성

네트워크 접근이 가능하도록 Service 를 생성해 줍니다.

테스트 목적이긴 하지만 외부 네트워크에서 접근이 되도록 해보겠습니다.

Service yaml 파일을 작성합니다.

# vi service.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  selector:
    app: nginx
  type: NodePort
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30080  # 여기에 원하는 NodePort 값을 지정하세요. (범위 : 30000~32767)

 

* 참고

Service 에서 생성할 type 은 ClusterIP, NodePort, LoadBalancer 가 있습니다.

- ClusterIP : 클러스터 내부 통신만 가능한 IP

- NodePort : worker 노드의 IP 와 지정한 포트 (30000~32767 로 제한) 를 이용해 Pod 에 연결 가능

- LoadBalancer : 별도의 공인 IP 가 할당되고, 포트를 마음대로 사용 가능 (베어메탈 환경에서는 MetalLB 를 설치 필요)

 

작성한 yaml 파일을 적용하여 생성합니다.

# kubectl apply -f service.yaml

service/nginx created

 

Service 생성시 Endpoint 도 같이 생성되는데, 두가지 정보를 함께 출력해보면 아래와 같습니다.

# kubectl get services,ep

NAME    TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
nginx   NodePort   10.110.222.108   <none>        80:30080/TCP   17s


NAME    ENDPOINTS        AGE
nginx   10.101.1.66:80   17s

 

외부 네트워크에서 접근되는지 확인합니다.

접근할 IP 는 Pod 가 위치하는 worker 노드인데, 아래 명령으로 확인 가능합니다.

# kubectl get pod -o wide

NAME                                READY   STATUS    RESTARTS   AGE     IP            NODE      NOMINATED NODE   READINESS GATES
nginx-deployment-694db9fb84-b5h2r   1/1     Running   0          7m22s   10.101.1.66   worker2   <none>           <none>

 

worker2 노드인것을 확인하였으며, 외부에서 worker2 노드의 공인 IP 와 위에서 설정한 포트 30080 으로 접근시 nginx 초기페이지가 출력되는것이 확인됩니다. 예제에서는 worker2 노드의 공인 IP 로 연결하였지만 실제로는 꼭 worker2 노드의 공인 IP 로 할 필요는 없습니다. NodePort 의 경우 master 또는 어떤 worker 노드로 연결하던 설정한 Pod 로 연결됩니다.

# curl 115.68.249.176:30080

 

5) Ingress 생성

Ingress 를 사용하면 도메인 연결이 가능합니다.

Ingress yaml 파일을 작성합니다.

# ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx
  namespace: sysdocu
spec:
  rules:
  - host: nginx.sysdocu.kr    # 사용할 도메인
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx    # 연결할 Service 이름
            port:
              number: 80    # 연결할 Service 포트 번호

 

작성한 yaml 파일을 적용합니다.

# ingress.networking.k8s.io/nginx created

 

Ingress 가 생성되었습니다.

# kubectl get ingress
NAME    CLASS    HOSTS              ADDRESS   PORTS   AGE
nginx   <none>   nginx.sysdocu.kr             80      30s

 

사용할 도메인 (nginx.sysdocu.kr) 은 DNS 에서 IP 를 worker 노드의 IP 로 미리 등록해 놓아야 합니다.

아래와 같이 접속이 확인되었습니다.

# curl nginx.sysdocu.kr:30080

 

nginx 와 같은 웹서버에서 사용하는 포트는 보통 80 또는 443 이지만, NodePort 사용시 번거롭게 30000~32767 사이의 포트 번호를 사용해야 연결이 됩니다. 포트 번호없이 도메인만으로 접속을 원하는 경우 MetalLB 를 구성해 공인 IP 를 할당해 주면 됩니다.

- MetalLB 설치 : https://sysdocu.tistory.com/1854

 

 

 

 

반응형

댓글()

[Android] APNG 사용하기

프로그래밍/ANDROID|2023. 8. 24. 08:10
반응형

움직이는 GIF 파일과 같이 움직이는 PNG 파일인 APNG 입니다.

GIF 보다 용량도 작고 고화질로 출력이 가능해 안드로이드의 아이콘이나 버튼으로 사용하기 좋습니다.

 

라이브러리 :  https://github.com/penfeizhou/APNG4Android

 

1. 준비

build.gradle 파일에 dependency 를 추가합니다.

...

repositories {
    mavenCentral()
}


...

APNG
dependencies {
    implementation 'com.github.penfeizhou.android.animation:apng:${VERSION}'
}


...

 

2. 사용

APNG 파일 (예: sysdocu.png) 은 assets 폴더에 저장합니다.

...

// asset 파일에서 불러오기
AssetStreamLoader assetLoader = new AssetStreamLoader(context, "sysdocu.png");

// APNG Drawable 생성
APNGDrawable apngDrawable = new APNGDrawable(assetLoader);

// 자동 실행
imageView.setImageDrawable(apngDrawable);

...

 

반응형

댓글()

오픈 클라우드 플랫폼 K-PaaS (구 PaaS-TA) 6.5 Container Platform Portal 사용하기

리눅스/PaaS|2023. 8. 9. 10:40
반응형

본 문서는 공식 Documents 를 참고하여 실습한 후 작성된 내용으로 구성되어 있습니다.

https://github.com/PaaS-TA/paas-ta-container-platform/blob/master/use-guide/portal/container-platform-portal-guide.md

 

컨테이너 플랫폼 포털 URL 은 master 서버 (IP 또는 호스트명) 와 포트 32703 을 이용해 접근이 가능합니다.

http://115.68.142.67:32703

 

 

1. 일반 사용자 추가

 

컨테이너 플랫폼 포털 (이하 '포털') 로그인 화면에서 하단의 'Register' 버튼을 눌러 회원가입을 합니다.

회원가입시 Username 은 로그인 아이디에 해당 되는 부분이므로 영문 작성을 하면 되고, [Register] 버튼을 눌러 가입하면 '관리자의 승인이 필요' 하다는 메세지가 출력됩니다.

 

관리자는 승인을 기다리는 계정에 Namespace (프로젝트) 를 생성 후 Role (권한) 부여를 해주어야 합니다.

테스트 목적으로 아래와 같이 설정하였습니다.

 

1) Namespace 및 Role 생성

위치 : Clusters > Namespaces 화면에서 [생성] 버튼 클릭

> Name : mynamespace 입력 (소문자로만 입력해야 합니다)

> Resource Quotas : cp-low-resourcequota 선택

> Limit Ranges : cp-low-limitrange 선택

> [저장] 버튼을 눌러 생성합니다.

 

2) Namespace 및 Role 할당

위치 : 포털 로그인 > Managements > Users > 'User' 탭 > '비활성' 탭 클릭

> 사용자 계정을 클릭 후, 하단 [수정] 버튼을 누릅니다.

> Authority : [User] 로 선택합니다.

> Namespaces ⁄ Roles 옆에 [선택] 클릭합니다.

> 위에서 생성했던 mynamespace (cp-admin-role) 체크 > [선택 완료] > [수정]

 

이제 계정이 활성 처리 되었습니다.

admin 을 로그아웃하고 일반 사용자 계정으로 로그인합니다.

 

 

2. 응용프로그램 배포

 

admin 계정으로는 모든 메뉴의 권한이 열려 있기 때문에 K-PaaS 에서 제공하는 기능을 모두 사용할 수 있습니다.

여기에서는 위에서 생성했던 일반 사용자 계정으로 응용프로그램을 배포하는 과정을 설명하겠습니다.

 

1) Deployment 생성

컨테이너를 다운로드 받고 응용프로그램을 배포할 수 있습니다.

위치 : 포털 로그인 > Workloads > Deployments

> [생성] 버튼을 누릅니다.

> YAML 입력창에 아래 내용을 작성하고 [저장] 버튼을 누릅니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

 

저장과 동시에 자동으로 yaml 설정값이 적용되며, Deployments 는 물론이고 Pods 와 ReplicaSets 메뉴에서도 관련 정보가 확인됩니다.

 

2) Services 생성

서비스를 NodePort 형식으로 생성하면 외부에서 응용 프로그램으로 연결이 가능해집니다.

위치 : 포털 로그인 > Services > Services

> [생성] 버튼을 누릅니다.

> YAML 입력창에 아래 내용을 작성하고 [저장] 버튼을 누릅니다.

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  type: NodePort
  ports:
  - name: nginx-port
    nodePort: 30001
    port: 80
    targetPort: 80

 

* Port 설명

- nodePort: 외부 네트워크에서 접속하는 포트 번호 입니다. (30000~32767 사이의 포트 번호를 사용) 이 포트는 Service Port 로 연결됩니다.

- port: Service 의 포트 번호 입니다. 이 포트는 targetPort 로 연결됩니다.

- targetPort: Pod 의 포트 입니다.

- 기본 80 포트 연결을 원할 경우 type 을 LoadBalancer 로 변경해야 합니다.

 

3) Ingresses 생성

개인이 소유하고 있는 도메인을 사용하는 방법입니다.

위치 : 포털 로그인 > Services > Ingresses

> [생성] 버튼을 누릅니다.

> Name : myingress 입력 (소문자로만 입력해야 합니다)

> Host : test.sysdocu.kr 입력 (네임서버 설정 IP 는 master node, worker node 어느것이든 상관 없습니다)

> Path : Prefix 선택, / 입력

> Target : 위에서 생성했던 Service 명, Port : 80 입력

> [저장] 버튼을 누릅니다.

 

4) 응용프로그램 접속

웹브라우저를 통해 준비된 도메인과 포트번호로 접근하면 웹서버 기본페이지가 출력됩니다.

http://test.sysdocu.kr:30001

 

5) 볼륨 추가

외부 스토리지의 일정 용량을 할당 받아 Pod 에 연결하는 방법입니다.

위치 : 포털 로그인 > Persistent Volume Claims

> [생성] 버튼을 누릅니다.

> YAML 입력창에 아래 내용을 작성하고 [저장] 버튼을 누릅니다.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

 

볼륨을 위에서 생성했던 Pod 에 붙여 보겠습니다.

위치 : 포털 로그인 > Workloads > Deployments

> Deployments 이름 선택

> 아래 [수정] 버튼을 누릅니다.

> YAML 입력창에 아래 파란색으로 표시한 내용을 추가하고 [저장] 버튼을 누릅니다.

...

        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /backup
          name: my-pvc
      dnsPolicy: ClusterFirst

...

      terminationGracePeriodSeconds: 30
      volumes:
      - name: my-pvc
        persistentVolumeClaim:
          claimName: nginx-pvc
status:

...

 

Deployment 를 수정하면 Pod 가 재생성 됩니다.

Pod 이름을 확인하고, Pod bash 쉘에 진입하여 파티션을 확인합니다.

$ kubectl get pod -n mynamespace
NAME                               READY   STATUS    RESTARTS   AGE
nginx-deployment-b5cd59b6c-zj7pg   1/1     Running   0          1m33s

 

$ kubectl exec -it nginx-deployment-b5cd59b6c-zj7pg -n mynamespace -- /bin/bash

# df -h
Filesystem                                                                        Size  Used Avail Use% Mounted on
overlay                                                                            20G   11G  8.9G  54% /
tmpfs                                                                              64M     0   64M   0% /dev
tmpfs                                                                             3.9G     0  3.9G   0% /sys/fs/cgroup
shm                                                                                64M     0   64M   0% /dev/shm
tmpfs                                                                             795M  5.0M  790M   1% /etc/hostname
172.16.1.32:/data/mynamespace-nginx-pvc-pvc-4bde4a92-4288-415f-bba7-ca99bf4fb7fe   20G  2.7G   18G  14% /backup
/dev/vda1                                                                          20G   11G  8.9G  54% /etc/hosts
tmpfs                                                                             500M   12K  500M   1% /run/secrets/kubernetes.io/serviceaccount
tmpfs                                                                             3.9G     0  3.9G   0% /proc/acpi
tmpfs                                                                             3.9G     0  3.9G   0% /proc/scsi
tmpfs                                                                             3.9G     0  3.9G   0% /sys/firmware

 

* 참고

PVC 를 1G 로 설정했는데, 20G 로 보이는 이유는 NFS 를 PV (Persistent Volume) 로 사용하기 때문입니다.

NFS 에서는 계정별 Quota 설정이 없으므로 공유디렉토리 총 사용량이 출력됩니다.

할당받은 용량으로 보이길 원할 경우 Ceph, ISCSI, GlusterFS 등 용량 개별 할당이 가능한 PV 로 사용하는 방법이 있습니다.

 

6) ConfigMaps

ConfigMap 은 어플리케이션의 환경 설정 정보나 구성 값들을 분리하여 저장하는 리소스입니다. 이를 통해 설정 값들을 어플리케이션 코드와 분리하여 관리하고, 환경별로 다른 설정을 제공하거나 변경 사항을 쉽게 적용할 수 있습니다.

 

다음은 ConfigMap 의 database-url 설정 값을 DATABASE_URL 환경 변수로 설정하여 Pod 에서 사용하는 예시 입니다. 이렇게 설정한 값이 Pod 내의 환경 변수로 주입되어 어플리케이션에서 사용할 수 있습니다.

위치 : 포털 로그인 > ConfigMaps > ConfigMaps

> [생성] 버튼을 누릅니다.

> YAML 입력창에 아래 내용을 작성하고 [저장] 버튼을 누릅니다.

apiVersion: v1
kind: ConfigMap
metadata:
  name: my-config
data:
  database-url: "mysql://sysdocu:12345678@db.sysdocu.kr/testdb"

 

그리고 Pod 에서 ConfigMap 을 사용할 수 있도록 Deployment 설정을 수정해줍니다.

위치 : 포털 로그인 > Workloads > Deployments

> Deployments 이름 선택

> 아래 [수정] 버튼을 누릅니다.

> YAML 입력창에 아래 파란색으로 표시한 내용을 추가하고 [저장] 버튼을 누릅니다.

...

      containers:
      - image: nginx
        imagePullPolicy: Always
        env:
          - name: DATABASE_URL
            valueFrom:
              configMapKeyRef:
                name: my-config
                key: database-url
        name: nginx

...

 

Pod 에서 변수를 확인해보겠습니다.

Pod 이름을 확인하고, Pod bash 쉘에 진입하여 변수를 잘 받아왔는지 확인합니다.

$ kubectl get pod -n mynamespace
NAME                               READY   STATUS    RESTARTS   AGE
nginx-deployment-799d57d87-zwjsz   1/1     Running   0          25s

 

$ kubectl exec -it nginx-deployment-799d57d87-zwjsz -n mynamespace -- /bin/bash

# echo $DATABASE_URL
mysql://sysdocu:12345678@db.sysdocu.kr/testdb

 

7) Managements

Managements 에서는 아래 기능 설정이 가능합니다.

- Roles : 작업에 대한 권한을 정의

- Resource Quotas : 네임스페이스 내의 모든 Pod, 리소스 및 객체의 사용량을 관리

- Limit Ranges : 컨테이너 및 Pod의 리소스 사용을 제한하는 데 사용

 

따로 필요한 부분만 설정하여 사용이 가능하지만 여기 예제에서는 한 번에 설정하고 적용하도록 하겠습니다.

아래 설정값을 먼저 작성해둡니다.

위치 : 포털 로그인 > Managements > Roles

> [생성] 버튼을 누릅니다.

> YAML 입력창에 아래 내용을 작성하고 [저장] 버튼을 누릅니다.

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: mynamespace
  name: my-role
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

 

my-role 이라는 Role 에 pods 리소스에 대한 get, list, watch 명령을 수행할 수 있는 권한을 주었습니다.

이어서 Resource Quotas 를 작성합니다.

 

위치 : 포털 로그인 > Managements > Resource Quotas

> [생성] 버튼을 누릅니다.

> YAML 입력창에 아래 내용을 작성하고 [저장] 버튼을 누릅니다.

apiVersion: v1
kind: ResourceQuota
metadata:
  namespace: mynamespace
  name: my-resource-quota
spec:
  hard:
    pods: "5"
    requests.cpu: "1"
    requests.memory: 1Gi
    limits.cpu: "2"
    limits.memory: 2Gi

 

my-resource-quota 라는 Resource Quota 는 네임스페이스 내에서 최대 5개의 Pod 를 생성하며, CPU 및 메모리에 대한 요청과 제한 값을 설정하였습니다.

 

* 참고 : 권한 상승

YAML 저장시 "해당 리소스에 접근할 수 있는 권한이 없습니다." 라는 메세지가 출력될 경우, 포털 admin 계정으로 현재 계정에 대해 권한을 상승시켜주면 됩니다.

위치 : admin 계정으로 포털 로그인 > Managements > Users > 'User' 탭

> 사용자 계정을 클릭 후 하단 [수정] 버튼을 누릅니다.

Authority : [Cluster Admin] 으로 변경 후 [저장] 버튼을 누릅니다.

> admin 계정을 로그아웃 하고 다시 일반 계정으로 로그인합니다.

> 위 Resource Quota 를 생성합니다.

 

이어서 Limit Ranges 를 작성합니다.

위치 : 포털 로그인 > Managements > Limit Ranges

> [생성] 버튼을 누릅니다.

> YAML 입력창에 아래 내용을 작성하고 [저장] 버튼을 누릅니다.

apiVersion: v1
kind: LimitRange
metadata:
  namespace: mynamespace
  name: my-limit-range
spec:
  limits:
  - type: Container
    max:
      memory: 500Mi
    default:
      memory: 100Mi
    defaultRequest:
      memory: 50Mi

 

my-limit-range 라는 Limit Range 를 생성하여 컨테이너의 메모리에 대한 제한과 요청 값을 설정하였습니다.

 

Resource Quota, Limit Range 는 네임스페이스 내에서 생성해 두기만 하면 이후에 생성되는 Pod 에 자동 적용이 됩니다.

그리고 Role 은 일반적으로 Kubernetes 환경에서 사용하려면 Role Binding 과 ServiceAccount 를 추가로 생성해서 Deployment 에 연결시켜줘야 하지만, K-PaaS 에서는 Role 을 만들고 admin 계정으로 특정 계정의 Namespace 와 Role 을 선택해 주기만 하면 됩니다.

위에서 미리 생성했던 Role 을 계정에 적용해 보겠습니다.

우선, 일반 계정을 로그아웃 하고 admin 계정으로 로그인 합니다.

위치 : 포털 로그인 > Managements > Users

> 'Administrator' 탭에서 계정 이름 선택

> 아래 [수정] 버튼을 누릅니다.

> Authority 값을 Cluster Admin 에서 User 로 변경하고

> 바로 아래에 있는 Namespaces ⁄ Roles 의 [선택] 버튼을 누릅니다.

> 만들었던 Namespace 와 Role 을 선택합니다. (예 : mynamespace / my-role)

> [선택 완료] 버튼을 누릅니다.

> 하단의 [수정] 버튼을 누릅니다.

 

일반 계정에 권한이 적용되었습니다.

절차에서 알 수 있듯이 admin 계정이나 Cluster Admin 권한의 계정은 Role 적용이 되지 않습니다.

 

반응형

댓글()

iptables 명령으로 특정대역 22번 포트 허용 및 모두 차단

리눅스/Network|2023. 7. 31. 12:22
반응형

* 주의 : 룰에서 설정하는것이 아닌 iptables 명령을 통한 것이므로 리부팅이나 데몬 재시작시 룰이 초기화 되어 집니다.

 

iptables를 사용하여 22번 포트를 특정 대역에서만 열고 모두 차단하는 방법은 다음과 같습니다.
# iptables -A INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT
# iptables -A INPUT -p tcp --dport 22 -j DROP

 

위의 명령을 실행하면, 192.168.1.0/24 대역에서 오는 SSH (22번 포트) 접근은 허용되고, 나머지 모든 IP 주소에서 오는 SSH 접근은 차단됩니다.

기존의 규칙이 있다면 -I 옵션을 사용해서 적용해야 합니다.

# iptables -I INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT
# iptables -A INPUT -p tcp --dport 22 -j DROP

반응형

댓글()

Ubuntu 20.04 기본 방화벽 변경하기 (ufw -> iptables)

리눅스/Network|2023. 7. 27. 13:57
반응형

기본 방화벽을 중지합니다.
# systemctl disable --now ufw

iptables 를 설치합니다.

# apt-get -y update
# apt-get -y install iptables-persistent
(설치중 물음에는 'Yes' 로 대답)

 

룰 파일 위치는 아래와 같습니다.

여기에서는 예시로 작성했으니 서버 상황에 맞게 수정해서 사용하시면 됩니다.

# vi /etc/iptables/rules.v4

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

# Loopback 트래픽은 항상 허용합니다.
-A INPUT -i lo -j ACCEPT
-A OUTPUT -o lo -j ACCEPT

# ICMP 를 허용합니다.
-A INPUT -p icmp -m icmp --icmp-type any -j ACCEPT

# 특정 IP 주소에서 모든 포트로 들어오는 트래픽을 허용합니다.
-A INPUT -s 192.168.10.2 -p tcp -j ACCEPT
-A INPUT -s 172.16.1.0/24 -p tcp -j ACCEPT

# 이미 연결된 연결은 허용합니다.
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# 모든 아이피에서 포트 80번으로 들어오는 연결을 허용합니다.
-A INPUT -p tcp --dport 80 -j ACCEPT

# 마지막에 모든 트래픽을 거부합니다.
-A INPUT -j DROP
-A FORWARD -j DROP

COMMIT

 

iptables 가동하고, 부팅시 자동 실행되도록 합니다.

# systemctl enable --now iptables

 

적용된 iptables 룰을 확인합니다.

# iptables -nL

 

반응형

댓글()

[Openstack] powering-off 상태의 VM 을 강제로 리부팅 하는 방법

리눅스/OpenStack|2023. 7. 27. 10:47
반응형

VM 상태가 powering-off 라면 중지도 되지 않고, 리부팅도 되지 않습니다.

- 예시) VM 이름 : master

 

# openstack server show master |grep task_state
| OS-EXT-STS:task_state               | powering-off                                             |

 

이 상태에서 VM 을 중지할 경우 실패가 됩니다.

# openstack server stop master
Cannot 'stop' instance 17c0f56b-00c2-485d-9280-7d2cb09a6139 while it is in task_state powering-off (HTTP 409) (Request-ID: req-8380c8ea-fa5b-45bc-b16d-c5651a0b2281)

 

이때, 아래와 같이 nova 명령을 이용해 상태를 초기화 하고 경우에 따라 VM 중지 또는 시작 명령으로 서버를 재가동 할 수 있습니다.

# nova reset-state --active master
Reset state for server master succeeded; new state is active

# openstack server stop master

# openstack server start master
# openstack server show master |grep state
| OS-EXT-STS:power_state              | Running                                                  |
| OS-EXT-STS:task_state               | None                                                     |
| OS-EXT-STS:vm_state                 | active                                                   |

반응형

댓글()

Openstack VM 생성시 에러 {'code': 400, ..., 'message': "Host is not mapped to any cell"}

리눅스/OpenStack|2023. 7. 18. 11:47
반응형

컴퓨트 노드를 추가하고 VM (이름 : worker2) 을 생성할때 발생한 에러 입니다.

아래와 같이 상태를 확인하였습니다.

 

# openstack server show worker2 |grep fault
| fault                               | {'code': 400, 'created': '2023-07-18T02:32:17Z', 'message': "Host 'compute2' is not mapped to any cell"} |

 

이때 openstack compute service list 에 추가된 컴퓨트 노드가 정상으로 출력된다고 해도 아래와 같이 다시 명령을 실행해주세요.

nova-manage cell_v2 discover_hosts --verbose
Found 2 cell mappings.
Skipping cell0 since it does not contain hosts.
Getting computes from cell 'cell0': 12471ee6-907e-47d5-b002-b008d99b847b
Checking host mapping for compute host 'compute2': 8f3070ff-4173-4c06-a004-19eeabeacd97
Creating host mapping for compute host 'compute2': 8f3070ff-4173-4c06-a004-19eeabeacd97
Found 1 unmapped computes in cell: 12471ee6-907e-47d5-b002-b008d99b847b

 

그리고 다시 VM 을 생성하면 잘 될 것입니다.

 

반응형

댓글()

CentOS 7 에서 GlusterFS 설치 (단일 서버)

리눅스/OS 일반|2023. 7. 12. 15:55
반응형

GlusterFS 를 RAID 와 같은 여러가지 형태로 구성 가능하지만 본 매뉴얼에서는 단일 서버로 서비스하는 방법에 대해 기술하였습니다.

 

[사전 작업]
서버에 추가 Disk 를 연결하고 /data 디렉토리로 마운트 했습니다.
그리고 마운트 디렉토리 안에 gv0 이라는 Brick 디렉토리를 생성해 두었습니다.

Brick 디렉터리는 GlusterFS 볼륨에서 데이터를 저장하는 디렉터리를 뜻합니다.
- /data/gv0

 

1. 설치

호스트 명을 변경합니다.
# hostnamectl set-hostname gnode


호스트를 등록 합니다.
# vi /etc/hosts

127.0.0.1   localhost gnode

 

GlusterFS 설치를 위한 Repository 를 등록해줍니다.
등록은 yum 로 간단히 할 수 있습니다.
# yum -y install centos-release-gluster

 

GlusterFS 패키지를 설치합니다.
# yum -y install glusterfs glusterfs-libs glusterfs-server

서버 부팅시 glusterd 데몬이 자동 구동 되도록 하고, 현재 세션에서도 구동시켜줍니다.
# systemctl enable --now glusterd

 

설치된 버전을 확인합니다.

# glusterd --version
glusterfs 9.6
Repository revision: git://git.gluster.org/glusterfs.git
Copyright (c) 2006-2016 Red Hat, Inc. <https://www.gluster.org/>
GlusterFS comes with ABSOLUTELY NO WARRANTY.
It is licensed to you under your choice of the GNU Lesser
General Public License, version 3 or any later version (LGPLv3
or later), or the GNU General Public License, version 2 (GPLv2),
in all cases as published by the Free Software Foundation.

 

2. 볼륨 생성

Cluster Pool 을 구성합니다.

여러대로 구성할 경우 본 서버가 아닌 다른 서버를 peer 로 등록해야 하지만, 단일 서버로 구성할 예정이므로 추가할 peer 가 없습니다.

Pool 을 구성하는 peer 리스트를 확인합니다.

# gluster pool list
UUID Hostname  State
eb4dba8d-df9a-4471-962a-103200830683 localhost Connected 

 

볼륨을 구성합니다.

# gluster volume create gv0 gnode:/data/gv0
volume create: gv0: success: please start the volume to access data

 

* 에러 출력시

volume create: gv0: failed: The brick gnode:/data/gv0 is being created in the root partition. It is recommended that you don't use the system's root partition for storage backend. Or use 'force' at the end of the command if you want to override this behavior.

위와 같은 에러 메세지는 별도의 파티션 디렉토리가 아니고 루트 (/) 파티션에서 생성한 디렉토리에서 볼륨을 구성할때 경고 메세지가 출력되는 것입니다. 추가 디스크나 별도의 파티션을 추가하지 않았지만 테스트 목적으로 구성하고 싶다면, 명령 뒤에 force 문자를 추가하여 실행할 수 있습니다.

예) gluster volume create gv0 gnode:/data/gv0 force

 

gv0 볼륨을 시작합니다.

# gluster volume start gv0

volume start: gv0: success

 

gv0 볼륨 상태를 확인합니다.

# gluster volume info gv0

 
Volume Name: gv0
Type: Distribute
Volume ID: 5aeec667-d4f8-433c-8fec-91ae275569ea
Status: Started
Snapshot Count: 0
Number of Bricks: 1
Transport-type: tcp
Bricks:
Brick1: gnode:/data/gv0
Options Reconfigured:
storage.fips-mode-rchecksum: on
transport.address-family: inet
nfs.disable: on

3. Client 마운트

GlusterFS 에서는 몇가지 마운트 방법을 제공합니다. GlusterFS (FUSE), NFS, iSCSI, SMB 방식인데 여기에서는 일반적인 FUSE 방식을 설명하겠습니다.

Client 에서 마운트에 필요한 패키지를 설치하고 마운트를 합니다.

GlusterFS 서버를 찾을 수 있도록 도메인을 연결하면 좋겠지만 현재 테스트 환경에서는 hosts 파일을 이용하였으므로 Client 에서도 찾을 수 있도록 /etc/hosts 파일에 아래 내용을 작성해 줍니다.

# vi /etc/hosts

127.0.0.1   localhost localhost.localdomain
192.168.10.10 gnode

 

클라이언트 패키지를 설치하고 마운트를 합니다.

# yum -y install glusterfs-client  // CentOS 명령어 이므로 Ubuntu 사용자는 apt 명령 사용

# mkdir /backup

# mount -t glusterfs gnode:/gv0 /backup

# df -h
파일 시스템     크기  사용  가용 사용% 마운트위치
tmpfs           1.5G  2.3M  1.5G    1% /run
/dev/sda2       214G   29G  174G   15% /
tmpfs           7.3G   66M  7.3G    1% /dev/shm
tmpfs           5.0M  4.0K  5.0M    1% /run/lock
tmpfs           1.5G  192K  1.5G    1% /run/user/1000
gnode:/gv0       10G  135M  9.9G    2% /backup

 

* 참고

디렉토리에 쿼터를 적용하는 방법이나 GlusterFS 를 RAID 서버와 같이 여러대로 구성하는 방법은 아래 포스팅을 참고해주세요.

https://sysdocu.tistory.com/1821

 

반응형

댓글()

2. Openstack Image, Flavor, Network, VM 순차적으로 생성하기

리눅스/OpenStack|2023. 7. 10. 08:35
반응형

Openstack 인프라 구성이 완료된 상태에서 진행합니다.

참고 : https://sysdocu.tistory.com/1833

 

 

1. 이미지 생성

 

OS 설치용 이미지를 Openstack 에 등록해야 합니다.

 

CentOS 7 cloud 버전 이미지를 다운로드 합니다.

# wget https://mirrors.cloud.tencent.com/centos-cloud/centos/7/images/CentOS-7-x86_64-GenericCloud-2009.qcow2

 

이미지 파일을 등록합니다.

# openstack image create "CentOS7" --file CentOS-7-x86_64-GenericCloud-2009.qcow2 --disk-format qcow2 --container-format bare --public

+------------------+---------------------------------------------------------------------------------------------------------------------------------------------+
| Field            | Value                                                                                                                                       |
+------------------+---------------------------------------------------------------------------------------------------------------------------------------------+
| container_format | bare                                                                                                                                        |
| created_at       | 2023-07-10T01:23:08Z                                                                                                                        |
| disk_format      | qcow2                                                                                                                                       |
| file             | /v2/images/acbe118e-6881-4ecf-8447-868864150c81/file                                                                                        |
| id               | acbe118e-6881-4ecf-8447-868864150c81                                                                                                        |
| min_disk         | 0                                                                                                                                           |
| min_ram          | 0                                                                                                                                           |
| name             | CentOS7                                                                                                                                     |
| owner            | 677861619c5445368a353ebeb0bcba2b                                                                                                            |
| properties       | os_hidden='False', owner_specified.openstack.md5='', owner_specified.openstack.object='images/CentOS7', owner_specified.openstack.sha256='' |
| protected        | False                                                                                                                                       |
| schema           | /v2/schemas/image                                                                                                                           |
| status           | queued                                                                                                                                      |
| tags             |                                                                                                                                             |
| updated_at       | 2023-07-10T01:23:08Z                                                                                                                        |
| visibility       | public                                                                                                                                      |
+------------------+---------------------------------------------------------------------------------------------------------------------------------------------+

 

생성된 이미지를 확인합니다.

# openstack image list

+--------------------------------------+---------+--------+
| ID                                   | Name    | Status |
+--------------------------------------+---------+--------+
| acbe118e-6881-4ecf-8447-868864150c81 | CentOS7 | active |
+--------------------------------------+---------+--------+

 

* Ubuntu Cloud 이미지는 아래 공식 사이트에서 다운로드가 가능합니다.

https://cloud-images.ubuntu.com/

 

 

2. Flavor 생성

 

Flavor는 VM의 리소스 (CPU, 메모리, 디스크 등) 와 구성을 정의 합니다.

 

Flavor 를 생성합니다.

형식) openstack flavor create --ram <RAM> --disk <DISK> --vcpus <VCPUS> --public <FLAVOR_NAME>

# openstack flavor create --ram 2048 --disk 20 --vcpus 2 --public myflavor

+----------------------------+--------------------------------------+
| Field                      | Value                                |
+----------------------------+--------------------------------------+
| OS-FLV-DISABLED:disabled   | False                                |
| OS-FLV-EXT-DATA:ephemeral  | 0                                    |
| disk                       | 20                                   |
| id                         | 7e94605d-ace3-4980-94ad-fa49b36c4735 |
| name                       | myflavor                             |
| os-flavor-access:is_public | True                                 |
| properties                 |                                      |
| ram                        | 2048                                 |
| rxtx_factor                | 1.0                                  |
| swap                       |                                      |
| vcpus                      | 2                                    |
+----------------------------+--------------------------------------+

 

생성된 Flavor 를 확인합니다.

# openstack flavor list
+--------------------------------------+----------+------+------+-----------+-------+-----------+
| ID                                   | Name     |  RAM | Disk | Ephemeral | VCPUs | Is Public |
+--------------------------------------+----------+------+------+-----------+-------+-----------+
| 7e94605d-ace3-4980-94ad-fa49b36c4735 | myflavor | 2048 |   20 |         0 |     2 | True      |
+--------------------------------------+----------+------+------+-----------+-------+-----------+

 

 

3. Network 생성

 

먼저 기본 provider 네트워크를 생성합니다.
# openstack network create --share --external --provider-physical-network provider --provider-network-type flat provider
+---------------------------+--------------------------------------+
| Field                     | Value                                |
+---------------------------+--------------------------------------+
| admin_state_up            | UP                                   |
| availability_zone_hints   |                                      |
| availability_zones        |                                      |
| created_at                | 2023-07-17T06:08:56Z                 |
| description               |                                      |
| dns_domain                | None                                 |
| id                        | b536c267-4a33-4068-a0da-4748a1cbfc97 |
| ipv4_address_scope        | None                                 |
| ipv6_address_scope        | None                                 |
| is_default                | False                                |
| is_vlan_transparent       | None                                 |
| mtu                       | 1550                                 |
| name                      | provider                             |
| port_security_enabled     | True                                 |
| project_id                | 677861619c5445368a353ebeb0bcba2b     |
| provider:network_type     | flat                                 |
| provider:physical_network | provider                             |
| provider:segmentation_id  | None                                 |
| qos_policy_id             | None                                 |
| revision_number           | 1                                    |
| router:external           | External                             |
| segments                  | None                                 |
| shared                    | True                                 |
| status                    | ACTIVE                               |
| subnets                   |                                      |
| tags                      |                                      |
| updated_at                | 2023-07-17T06:08:56Z                 |
+---------------------------+--------------------------------------+

* 옵션 설명
--share : 모든 프로젝트가 가상 네트워크 사용하도록 허용
--external : 가상 네트워크가 외부에 연결되도록 함 (내부 네트워크 사용시 --internal)

다음 파일에 옵션이 설정되었는지 확인하고 없으면 입력합니다.
# vi /etc/neutron/plugins/ml2/ml2_conf.ini
[ml2_type_flat]
flat_networks = provider

# vi /etc/neutron/plugins/ml2/linuxbridge_agent.ini
[linux_bridge]
physical_interface_mappings = provider:eno1

위 eno1 은 네트워크 장치명입니다.
설정이 변경된 경우 neutron 을 재시작 합니다.
# systemctl restart neutron-server

external 네트워크에 서브넷을 생성합니다.
VM 에 할당할 외부 IP 대역 및 게이트웨이 정보를 입력합니다.
# openstack subnet create --network provider --allocation-pool start=115.68.142.66,end=115.68.142.94 --dns-nameserver 8.8.8.8 --gateway 115.68.142.65 --subnet-range 115.68.142.64/27 provider
+----------------------+--------------------------------------+
| Field                | Value                                |
+----------------------+--------------------------------------+
| allocation_pools     | 115.68.142.66-115.68.142.94          |
| cidr                 | 115.68.142.64/27                     |
| created_at           | 2023-07-17T06:12:12Z                 |
| description          |                                      |
| dns_nameservers      | 8.8.8.8                              |
| dns_publish_fixed_ip | None                                 |
| enable_dhcp          | True                                 |
| gateway_ip           | 115.68.142.65                        |
| host_routes          |                                      |
| id                   | d2346f72-dd3b-4ef2-8065-0fd34d50177f |
| ip_version           | 4                                    |
| ipv6_address_mode    | None                                 |
| ipv6_ra_mode         | None                                 |
| name                 | provider                             |
| network_id           | b536c267-4a33-4068-a0da-4748a1cbfc97 |
| prefix_length        | None                                 |
| project_id           | 677861619c5445368a353ebeb0bcba2b     |
| revision_number      | 0                                    |
| segment_id           | None                                 |
| service_types        |                                      |
| subnetpool_id        | None                                 |
| tags                 |                                      |
| updated_at           | 2023-07-17T06:12:12Z                 |
+----------------------+--------------------------------------+


사용자 환경에 내부 네트워크 제공을 위해 사용자 환경을 로드 합니다.
테스트를 위해 admin 으로 VM 을 생성할 경우 바로 아래 명령은 넘어갑니다.
# source sysdocu-openrc

VM 끼리 내부 네트워크로 사용할 서브넷을 생성합니다.
# openstack network create selfservice
+---------------------------+--------------------------------------+
| Field                     | Value                                |
+---------------------------+--------------------------------------+
| admin_state_up            | UP                                   |
| availability_zone_hints   |                                      |
| availability_zones        |                                      |
| created_at                | 2023-07-14T01:35:56Z                 |
| description               |                                      |
| dns_domain                | None                                 |
| id                        | 30fbd00c-5968-40bf-a6e6-6e1b3307a232 |
| ipv4_address_scope        | None                                 |
| ipv6_address_scope        | None                                 |
| is_default                | False                                |
| is_vlan_transparent       | None                                 |
| mtu                       | 1500                                 |
| name                      | selfservice                          |
| port_security_enabled     | True                                 |
| project_id                | 677861619c5445368a353ebeb0bcba2b     |
| provider:network_type     | vxlan                                |
| provider:physical_network | None                                 |
| provider:segmentation_id  | 477                                  |
| qos_policy_id             | None                                 |
| revision_number           | 1                                    |
| router:external           | Internal                             |
| segments                  | None                                 |
| shared                    | False                                |
| status                    | ACTIVE                               |
| subnets                   |                                      |
| tags                      |                                      |
| updated_at                | 2023-07-14T01:35:56Z                 |
+---------------------------+--------------------------------------+

# openstack subnet create --network selfservice --dns-nameserver 8.8.8.8 --gateway 172.16.1.1 --subnet-range 172.16.1.0/24 selfservice
+----------------------+--------------------------------------+
| Field                | Value                                |
+----------------------+--------------------------------------+
| allocation_pools     | 172.16.1.2-172.16.1.254              |
| cidr                 | 172.16.1.0/24                        |
| created_at           | 2023-07-14T01:36:07Z                 |
| description          |                                      |
| dns_nameservers      | 8.8.8.8                              |
| dns_publish_fixed_ip | None                                 |
| enable_dhcp          | True                                 |
| gateway_ip           | 172.16.1.1                           |
| host_routes          |                                      |
| id                   | d577dadf-9d16-49ef-b495-69412745bc7b |
| ip_version           | 4                                    |
| ipv6_address_mode    | None                                 |
| ipv6_ra_mode         | None                                 |
| name                 | selfservice                          |
| network_id           | 30fbd00c-5968-40bf-a6e6-6e1b3307a232 |
| prefix_length        | None                                 |
| project_id           | 677861619c5445368a353ebeb0bcba2b     |
| revision_number      | 0                                    |
| segment_id           | None                                 |
| service_types        |                                      |
| subnetpool_id        | None                                 |
| tags                 |                                      |
| updated_at           | 2023-07-14T01:36:07Z                 |
+----------------------+--------------------------------------+

외부네트워크와 내부 네트워크를 연결하는 작업을 진행하기 위해 Router 를 생성합니다.
# openstack router create router
+-------------------------+--------------------------------------+
| Field                   | Value                                |
+-------------------------+--------------------------------------+
| admin_state_up          | UP                                   |
| availability_zone_hints |                                      |
| availability_zones      |                                      |
| created_at              | 2023-07-17T06:13:12Z                 |
| description             |                                      |
| distributed             | False                                |
| external_gateway_info   | null                                 |
| flavor_id               | None                                 |
| ha                      | False                                |
| id                      | 12bb1577-1184-4aaf-a285-175579a0f13f |
| name                    | router                               |
| project_id              | 677861619c5445368a353ebeb0bcba2b     |
| revision_number         | 1                                    |
| routes                  |                                      |
| status                  | ACTIVE                               |
| tags                    |                                      |
| updated_at              | 2023-07-17T06:13:12Z                 |
+-------------------------+--------------------------------------+

# openstack router add subnet router selfservice
# openstack router set router --external-gateway provider

연결을 확인합니다.
# source admin-openrc
# openstack router list
+--------------------------------------+--------+--------+-------+----------------------------------+-------------+-------+
| ID                                   | Name   | Status | State | Project                          | Distributed | HA    |
+--------------------------------------+--------+--------+-------+----------------------------------+-------------+-------+
| 12bb1577-1184-4aaf-a285-175579a0f13f | router | ACTIVE | UP    | 677861619c5445368a353ebeb0bcba2b | False       | False |
+--------------------------------------+--------+--------+-------+----------------------------------+-------------+-------+

 

 

4. VM 생성

 

VM 초기 구성을 변경하기 위해 관련 패키지를 설치하고 파일을 생성합니다.

ubuntu 일반계정과 root 관리자 계정 두 가지 로그인 방법이 있으므로 상황에 맞게 사용하시면 됩니다.

# apt-get -y install cloud-init

# vi temp.sh

(root 계정으로 로그인 허용)

#cloud-config
users:
  - name: root
chpasswd:
  list: |
    root:12345678@#$%
  expire: False
runcmd:
  - 'sed -i "s/^#PermitRootLogin .*/PermitRootLogin yes/" /etc/ssh/sshd_config'
  - 'sed -i "s/^PasswordAuthentication no/PasswordAuthentication yes/" /etc/ssh/sshd_config'
  - 'systemctl restart sshd'

 

(ubuntu 기본 계정으로 로그인 허용)

#cloud-config
users:
  - name: ubuntu
chpasswd:
  list: |
    ubuntu:12345678@#$%
  expire: False
runcmd:
  - 'sed -i "s/^PasswordAuthentication no/PasswordAuthentication yes/" /etc/ssh/sshd_config'
  - 'systemctl restart sshd'
  - 'sudo usermod -aG sudo ubuntu'
  - 'sed -i "s/\/ubuntu:\/bin\/sh/\/ubuntu:\/bin\/bash/" /etc/passwd'

 

(root 패스워드를 설정하고, sudo 권한 가진 ubuntu 계정 생성)

#cloud-config
users:
  - name: ubuntu
chpasswd:
  list: |
    ubuntu:12345678@#$%
  expire: False
runcmd:
  - 'sed -i "s/^PasswordAuthentication no/PasswordAuthentication yes/" /etc/ssh/sshd_config'
  - 'systemctl restart sshd'
  - 'useradd -m -d /home/ubuntu -s /bin/bash -G sudo ubuntu'
  - 'echo "ubuntu:12345678@#$%" | chpasswd'
  - 'echo "ubuntu  ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers'

 

Image 와 Flavor 를 이용해 VM 을 생성합니다.

VM 생성할때는 위에서 생성한 Flavor, Image, Key, (내부) Network 정보를 포함해야 합니다.

형식) openstack server create --flavor <FLAVOR_NAME> --image <IMAGE_NAME> --nic net-id <NETWORK_NAME> --user-data <INITIALIZE_FILE> <INSTANCE_NAME>

# openstack server create --flavor myflavor --image "CentOS7" --nic net-id=selfservice --user-data /root/temp.sh myinstance
+-------------------------------------+-------------------------------------------------+
| Field                               | Value                                           |
+-------------------------------------+-------------------------------------------------+
| OS-DCF:diskConfig                   | MANUAL                                          |
| OS-EXT-AZ:availability_zone         |                                                 |
| OS-EXT-SRV-ATTR:host                | None                                            |
| OS-EXT-SRV-ATTR:hypervisor_hostname | None                                            |
| OS-EXT-SRV-ATTR:instance_name       |                                                 |
| OS-EXT-STS:power_state              | NOSTATE                                         |
| OS-EXT-STS:task_state               | scheduling                                      |
| OS-EXT-STS:vm_state                 | building                                        |
| OS-SRV-USG:launched_at              | None                                            |
| OS-SRV-USG:terminated_at            | None                                            |
| accessIPv4                          |                                                 |
| accessIPv6                          |                                                 |
| addresses                           |                                                 |
| adminPass                           | QSjCjKK3oiJi                                    |
| config_drive                        |                                                 |
| created                             | 2023-07-14T05:16:28Z                            |
| flavor                              | myflavor (7e94605d-ace3-4980-94ad-fa49b36c4735) |
| hostId                              |                                                 |
| id                                  | a23ff754-668f-4f9e-b517-376ae41ddc42            |
| image                               | CentOS7 (acbe118e-6881-4ecf-8447-868864150c81)  |
| key_name                            | None                                           |
| name                                | myinstance                                      |
| progress                            | 0                                               |
| project_id                          | 677861619c5445368a353ebeb0bcba2b                |
| properties                          |                                                 |
| security_groups                     | name='default'                                  |
| status                              | BUILD                                           |
| updated                             | 2023-07-14T05:16:28Z                            |
| user_id                             | 7ffedad885e1490e9f5598081077f5a8                |
| volumes_attached                    |                                                 |
+-------------------------------------+-------------------------------------------------+

 

root@controller:~# openstack server list
+--------------------------------------+------------+--------+-----------------------------------------+---------+----------+
| ID                                   | Name       | Status | Networks                                | Image   | Flavor   |
+--------------------------------------+------------+--------+-----------------------------------------+---------+----------+
| a23ff754-668f-4f9e-b517-376ae41ddc42 | myinstance | ACTIVE | selfservice=172.16.1.173 | CentOS7 | myflavor |
+--------------------------------------+------------+--------+-----------------------------------------+---------+----------+

 

여기에 외부 IP 를 할당해줍니다.

아래 명령을 실행하면 provider 에 할당된 네트워크 범위에서 1개의 IP 를 자동 생성 시킵니다.

# openstack floating ip create provider
+---------------------+--------------------------------------+
| Field               | Value                                |
+---------------------+--------------------------------------+
| created_at          | 2023-07-17T06:16:01Z                 |
| description         |                                      |
| dns_domain          | None                                 |
| dns_name            | None                                 |
| fixed_ip_address    | None                                 |
| floating_ip_address | 115.68.142.86                        |
| floating_network_id | b536c267-4a33-4068-a0da-4748a1cbfc97 |
| id                  | dcc8088b-c577-41dd-ae40-d0bdd97865ed |
| name                | 115.68.142.86                        |
| port_details        | None                                 |
| port_id             | None                                 |
| project_id          | 677861619c5445368a353ebeb0bcba2b     |
| qos_policy_id       | None                                 |
| revision_number     | 0                                    |
| router_id           | None                                 |
| status              | DOWN                                 |
| subnet_id           | None                                 |
| tags                | []                                   |
| updated_at          | 2023-07-17T06:16:01Z                 |
+---------------------+--------------------------------------+

 

생성된 외부 IP 를 확인합니다.

# openstack floating ip list
+--------------------------------------+---------------------+------------------+------+--------------------------------------+----------------------------------+
| ID                                   | Floating IP Address | Fixed IP Address | Port | Floating Network                     | Project                          |
+--------------------------------------+---------------------+------------------+------+--------------------------------------+----------------------------------+
| dcc8088b-c577-41dd-ae40-d0bdd97865ed | 115.68.142.86       | None             | None | b536c267-4a33-4068-a0da-4748a1cbfc97 | 677861619c5445368a353ebeb0bcba2b |
+--------------------------------------+---------------------+------------------+------+--------------------------------------+----------------------------------+

 

서버와 생생된 IP 를 연결해줍니다.

서버는 이름이나 ID 값 아무거나 넣어줘도 됩니다.

# openstack server add floating ip myinstance 115.68.142.86

 

IP 추가된것을 다시 확인합니다.
# openstack server list
+--------------------------------------+------------+--------+-----------------------------------------+---------+----------+
| ID                                   | Name       | Status | Networks                                | Image   | Flavor   |
+--------------------------------------+------------+--------+-----------------------------------------+---------+----------+
| a23ff754-668f-4f9e-b517-376ae41ddc42 | myinstance | ACTIVE | selfservice=172.16.1.173, 115.68.142.86 | CentOS7 | myflavor |
+--------------------------------------+------------+--------+-----------------------------------------+---------+----------+

 

참고로 ssh 로도 접속이 가능하지만 네트워크가 안될 경우 NoVNC 를 통해서 접근하는 방법은 아래와 같습니다.

# openstack console url show myinstance

+-------+-------------------------------------------------------------------------------------------+
| Field | Value                                                                                     |
+-------+-------------------------------------------------------------------------------------------+
| type  | novnc                                                                                     |
| url   | http://controller:6080/vnc_auto.html?path=%3Ftoken%3Ddd017af1-27f8-4f49-a611-fe36d5d34c01 |
+-------+-------------------------------------------------------------------------------------------+

 

URL 중 'controller' 는 접속이 가능한 도메인 또는 IP 로 대체하여 웹브라우저로 접속하면 컨트롤 가능한 콘솔 화면이 출력됩니다.

 

반응형

댓글()

PHP 소켓 (server.php, client.php) - 데이터 전달 예제

프로그래밍/PHP|2023. 7. 7. 12:47
반응형

PHP 를 이용해 Server 에서 소켓 파일을 만들어 실행한 상태에서 Client 가 데이터를 전달하는 예제입니다.

데이터 (Mac address) 를 보내면 Server 측에서 데이터 검증 후 출력하도록 작성하였습니다.

받은 데이터 로그는 /root/input_data.log 에 기록 됩니다.

 

# vi server.php

#!/usr/bin/php -q
<?php
set_time_limit(0);

define("_IP",    "0.0.0.0");
define("_PORT",  "80");

$sSock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($sSock, SOL_SOCKET, SO_REUSEADDR, 1);

socket_bind($sSock, _IP, _PORT);
socket_listen($sSock);

pcntl_signal(SIGCHLD, SIG_IGN); 

function msg($msg) {
    echo "SERVER >> ".$msg;
}

// 맥어드레스 형식 검증
function isMacAddress($str) {
    $pattern = '/^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/';
    return preg_match($pattern, $str);
}

while($sock = socket_accept($sSock)) {
    socket_getpeername($sock, $sockIp, $sockPort);
    msg("Client connect : ".$sockIp.":".$sockPort."\n");

    // 자식 프로세스 생성
    $pid = pcntl_fork();
    if($pid == -1) {
        msg("fork failed\n");
        exit;
    }
    if($pid == 0) {
        $input = socket_read($sock, 4096);

        // 헤더와 데이터 분리
        list($header, $data) = explode("\r\n\r\n", $input, 2);
        msg("Mac address : " . $data . "\n");

        // 결과 응답 및 Client 연결 해제
        if ($input != "") {
            socket_write($sock, "Received it well");
            msg("Client disconnect : ".$sockIp.":".$sockPort."\n");
            socket_close($sock);
        }

        // 데이터 검증
        if (isMacAddress($data)) {
            $validation = "OK";
        } else {
            $validation = "NotOK";
        }

        // 로그 기록
        $now = date("Y-m-d H:i:s");
        shell_exec("echo \"$now\" \"$data\" \"$validation\" >> /root/input_data.log");
        exit;
    }
}
?> 

 

맨 윗줄 #!/usr/bin/php -q 에는 실제 php 실행파일 경로를 적어줘야 합니다.

 

root 만 사용할 수 있도록 권한을 변경합니다.

# chmod 700 server.php

 

파일을 실행하여 80 포트를 오픈하고 client 의 수신을 대기합니다.

# php server.php

 

Client 파일을 만듭니다.

# vi client.php

<?php
$url = 'http://www.sysdocu.kr';    // 접속할 호스트명
$data = '00:d8:61:13:2a:b8';       // 전달하고 싶은 데이터 (여기에서는 Mac address)

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_exec($ch);
curl_close($ch);
?>

 

Server 측 소켓이 열린 상태에서 client.php 파일을 실행하면 미리 준비된 데이터가 전달 됩니다.

# php client.php

 

반응형

댓글()

오픈 클라우드 플랫폼 K-PaaS (구 PaaS-TA) 6.5 Container Platform 설치 (on Openstack)

리눅스/PaaS|2023. 7. 7. 08:54
반응형

현재는 오픈 클라우드 플랫폼 (K-PaaS) 이라는 이름으로 변경 되었지만, 이전에 사용하던 명칭 PaaS-TA 는 "Platform as a Service - 'Thank you' 의 속어인 'TA' 의 의미로, 한국지능정보사회진흥원 (NIA) 의 지원으로 다양한 국내 업체와 협업을 통해 만든 개방형 클라우드 플랫폼입니다. PaaS-TA 는 오픈소스 커뮤니티인 Cloud Foundry 를 기반으로 한 클라우드 플랫폼으로, 애플리케이션을 빠르고 쉽게 배포하고 실행할 수 있는 환경을 제공합니다. 그리고 다양한 기능과 서비스를 제공하여 개발자들이 애플리케이션을 효율적으로 구축하고 관리할 수 있도록 도와줍니다. 몇 가지 주요 기능은 다음과 같습니다.
- 애플리케이션 배포 및 관리 : 애플리케이션을 컨테이너화하여 배포하고, 애플리케이션 스케일링, 로드 밸런싱, 자동 복구 등을 관리할 수 있습니다. 개발자는 애플리케이션의 빌드, 배포, 롤백 등을 간편하게 수행할 수 있습니다.
- 서비스 관리 : 다양한 서비스를 제공하며, 데이터베이스, 메시징, 캐싱 등과 같은 백엔드 서비스를 애플리케이션에서 활용할 수 있습니다. 이를 통해 개발자는 별도의 서비스 구축 없이 필요한 기능을 활용할 수 있습니다.
- 스케줄링 및 자원 관리 : 애플리케이션의 스케줄링 및 자원 관리를 지원하여, 리소스의 효율적인 활용과 애플리케이션의 안정적인 운영을 도와줍니다.
- 모니터링 및 로깅 : 애플리케이션의 상태, 리소스 사용량, 로그 등을 모니터링하고 관리할 수 있는 기능을 제공합니다. 이를 통해 개발자는 애플리케이션의 성능과 안정성을 실시간으로 확인하고 문제를 해결할 수 있습니다.

PaaS-TA 는 오픈소스이므로 기업이나 개발자들은 소스 코드를 활용하여 자체적으로 구축하거나 커스터마이징 할 수 있습니다.

PaaS-TA CP (Container Platform) 설치 매뉴얼은 공식 문서를 기반으로 테스트하고 작성되었습니다.

- PaaS-TA Document : https://github.com/PaaS-TA/paas-ta-container-platform/blob/master/install-guide/Readme.md

- BOSH Document : http://bosh.io

- Cloud Foundry Document : https://docs.cloudfoundry.org

 

설치하는 PaaS-TA 버전은 6.5 이고, 서비스형 배포 방식이며, IaaS 환경은 Openstack 입니다.

Openstack 환경 구성은 아래 포스팅을 확인해주세요.

- Openstack 환경 구성 : https://sysdocu.tistory.com/1833

- VM 생성 : https://sysdocu.tistory.com/1836

 

[ 서버 준비 ]

1) Openstack 환경의 VM 4대를 준비합니다.

    - VM (최소) 사양 : 2 CPU / 8GB RAM

    - OS : Ubuntu 20.04

    - VM 4대 : Master node 1대 / Slave node 3대

2) VM 과 같은 내부 네트워크를 사용하는 곳에 NFS 서버를 추가로 준비합니다. (NFS 서버 설치 : 바로가기)

3) 모든 작업은 공식 Documents 에 안내되어 있는대로 ubuntu 계정을 사용합니다. 계정이 없거나 권한이 부족한 경우 아래절차로 설정해주세요.

- useradd -m -d /home/ubuntu -s /bin/bash -G sudo ubuntu
- echo "ubuntu:12345678@#" | chpasswd
- echo "ubuntu  ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
- mkdir /home/ubuntu/.ssh
- chown ubuntu.ubuntu /home/ubuntu/.ssh

 

 

1. Kubespray 설치

 

먼저, 설치가 잘 될 수 있도록 ufw 방화벽을 중지하고 OS 환경 업데이트를 진행합니다.

(모든 노드에서)

$ sudo systemctl disable --now ufw

$ sudo apt -y update

$ sudo apt -y upgrade

 

1) 설치 환경 구성

Kubespray 를 이용해 Kubernetes Cluster 를 쉽게 구성할 수 있습니다.

우선 각 서버를 지칭하고, 연결이 수월할 수 있도록 내부 IP 와 호스트명을 설정합니다.

 

(모든 노드에서)

$ sudo vi /etc/hosts

127.0.0.1 localhost
172.16.1.20 master
172.16.1.89 worker1
172.16.1.211 worker2
172.16.1.252 worker3
172.16.1.32 nfs

 

(각 노드에서)

$ sudo hostnamectl set-hostname master      // master 노드에서

$ sudo hostnamectl set-hostname worker1    // worker1 노드에서

$ sudo hostnamectl set-hostname worker2    // worker2 노드에서

$ sudo hostnamectl set-hostname worker3    // worker3 노드에서

$ sudo hostnamectl set-hostname nfs            // nfs 노드에서

 

Kubespray 설치를 위해 SSH Key 를 인벤토리의 모든 서버들에 복사합니다.

 

(Master 노드에서)

$ ssh-keygen -t rsa -m PEM
Generating public/private rsa key pair.
Enter file in which to save the key (/home/ubuntu/.ssh/id_rsa): (엔터)
Enter passphrase (empty for no passphrase): (엔터)
Enter same passphrase again: (엔터)
Your identification has been saved in /home/ubuntu/.ssh/id_rsa
Your public key has been saved in /home/ubuntu/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:7F9X4w2PGnTkju37pueRdcYvZZcDDmci0+hhoEJeOqA ubuntu@master
The key's randomart image is:
+---[RSA 3072]----+
| . . . .         |
|. + o . . o      |
|E  = .   * + +.  |
|    o  .o + *o...|
|        S.  ..++X|
|       .   . =.OX|
|        .   + *++|
|         . . = .+|
|          . . +Bo|
+----[SHA256]-----+

 

아래 명령으로 출력된 공개키를 모든 Master node (본서버 포함), Worker node 에 복사합니다.

$ cat ~/.ssh/id_rsa.pub

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDA7lkRlLtIYjeVdLOBCe+jahcDKacVV/hZkAYKEj49pX0EQ2sLRVTdaEkrFws3rBp9MRwI1SeAj3LiqKzpOYeltbIM2v20z1G8EiJIooMdtqlDAbiPlJI4Dz2/UU3KkEOcvP1OLhx9Ctd6xCQTSUuDkb0XenufKHiMFlN0S+fQPeE5YFMe7hpbFuuVTVMqpt1Nev1d2LXfecSj240J7gTC/CysMrdOOG7cyFGdl5CzA8SWKfaI+2R8p19j7fUhc1rYJcJ6CtMuw/jTahSkN+R+6kPvE1+xcTtN/bHJQ/HupTFNXaKs2u6aWrHCUVHe3ghGbyBaAKNVlHxiI2IB1pF98BVsAjfRzDTj2qHv/wVuNTroE0ux0ayu8wDTjNn9Vv6ou2BvfnAoS2qgBdRnKkfnXHcz+eHWl93m+EjfQ2KoEOLD23O91SecU0+SWpWF7egecy/6H7wRsgOlNMeNKMbeRGk9xG0uqE1ip7bsrAOFYYAbQI89Zc5AbzgArVF/j00= ubuntu@master

 

위 내용을 복사하여 아래와 같이 모든 노드에 저장합니다.

(모든 노드에서 - 본 master 서버 포함)

$ vi .ssh/authorized_keys

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDA7lkRlLtIYjeVdLOBCe+jahcDKacVV/hZkAYKEj49pX0EQ2sLRVTdaEkrFws3rBp9MRwI1SeAj3LiqKzpOYeltbIM2v20z1G8EiJIooMdtqlDAbiPlJI4Dz2/UU3KkEOcvP1OLhx9Ctd6xCQTSUuDkb0XenufKHiMFlN0S+fQPeE5YFMe7hpbFuuVTVMqpt1Nev1d2LXfecSj240J7gTC/CysMrdOOG7cyFGdl5CzA8SWKfaI+2R8p19j7fUhc1rYJcJ6CtMuw/jTahSkN+R+6kPvE1+xcTtN/bHJQ/HupTFNXaKs2u6aWrHCUVHe3ghGbyBaAKNVlHxiI2IB1pF98BVsAjfRzDTj2qHv/wVuNTroE0ux0ayu8wDTjNn9Vv6ou2BvfnAoS2qgBdRnKkfnXHcz+eHWl93m+EjfQ2KoEOLD23O91SecU0+SWpWF7egecy/6H7wRsgOlNMeNKMbeRGk9xG0uqE1ip7bsrAOFYYAbQI89Zc5AbzgArVF/j00= ubuntu@master

 

그리고 모든 노드에 NFS Client 패키지를 설치합니다.

아래에서 NFS 를 마운트 하기위해 사용할 예정입니다.

$ sudo apt -y install nfs-common

 

(Master 노드에서 - 이제 Worker 노드에서의 추가 작업은 없음)

Kubespray 설치파일을 다운로드 받고 설치를 이어갑니다.

아래의 branch_v1.4.x 는 특정 버전을 적는것이 아니라 문자 그대로 x 를 입력해야 합니다.

$ git clone https://github.com/PaaS-TA/paas-ta-container-platform-deployment.git -b branch_v1.4.x
Cloning into 'paas-ta-container-platform-deployment'...
remote: Enumerating objects: 11524, done.
remote: Counting objects: 100% (11523/11523), done.
remote: Compressing objects: 100% (5862/5862), done.
remote: Total 11524 (delta 4535), reused 11330 (delta 4347), pack-reused 1
Receiving objects: 100% (11524/11524), 274.90 MiB | 20.39 MiB/s, done.
Resolving deltas: 100% (4535/4535), done.
Updating files: 100% (7807/7807), done.

 

설치 경로로 이동해서 환경변수 파일을 수정합니다. 변수명에 해당되는 값을 입력하면 됩니다.

worker node 의 수가 더 많을경우 행을 더 추가하여 입력할 수 있습니다.

$ cd paas-ta-container-platform-deployment/standalone/single_control_plane

$ vi cp-cluster-vars.sh

#!/bin/bash

export MASTER_NODE_HOSTNAME=master
export MASTER_NODE_PUBLIC_IP=115.68.142.67
export MASTER_NODE_PRIVATE_IP=172.16.1.20

## Worker Node Count Info
export WORKER_NODE_CNT=3

## Add Worker Node Info
export WORKER1_NODE_HOSTNAME=worker1
export WORKER1_NODE_PRIVATE_IP=172.16.1.89
export WORKER2_NODE_HOSTNAME=worker2
export WORKER2_NODE_PRIVATE_IP=172.16.1.211
export WORKER3_NODE_HOSTNAME=worker3
export WORKER3_NODE_PRIVATE_IP=172.16.1.252

## Storage Type Info (eg. nfs, rook-ceph)
export STORAGE_TYPE=nfs
export NFS_SERVER_PRIVATE_IP=172.16.1.32

 

2) 에러 사전 조치

설치 전, 몇가지 에러 방지를 위해 아래와 같은 작업을 진행합니다.

공식 Documents 에서는 아래 내용이 빠져 있으며, 그대로 설치 (deploy-cp-cluster.sh 실행) 할 경우, OS 환경에 따라 여러개의 에러가 발생하는데, 아래는 에러 일부를 사전에 조치하는 방법입니다.

추후, 배포되는 설치 소스가 업데이트 되면서 아래 내용이 필요없게 되거나, 또 다른 조치 방법이 필요할 수 있습니다.

 

(1) NFS 공유 디렉토리 설정

NFS 를 사용할 경우 아래 파일에서 공유 디렉토리 위치를 변경해줘야 합니다.

파일에 기본 설정된 값은 /home/share/nfs 이므로, 실제 NFS 서버내에 구성한 공유 디렉토리가 /data 일때 아래와 같이 변경합니다.

설치중 deployment.yaml.ori 파일이 deployment.yaml 파일로 복사되므로 deployment.yaml 파일을 수정하지 않도록 주의합니다.

$ sed -i 's/home\/share\/nfs/data/' ../applications/nfs-provisioner-4.0.0/deployment.yaml.ori

또는 아래와 같이 파일을 열어 직접 변경합니다.

$ vi ../applications/nfs-provisioner-4.0.0/deployment.yaml.ori

...

            - name: NFS_PATH # do not change
              value: /data            # path to nfs directory setup
...
         nfs:
           server: {NFS_SERVER_PRIVATE_IP}
           path: /data
...

 

(2) nf_conntrack 사용

리눅스 커널 4.18 이상의 버전에는 nf_conntrack_ipv4 이름이 nf_conntrack 으로 변경되었습니다. 설치 스크립트에서는 nf_conntrack_ipv4 를 찾지못해 'Module nf_conntrack_ipv4 not found' 메세지가 출력되므로, 모듈명을 수정해 주어야 합니다.

$ sed -i 's/nf_conntrack_ipv4/nf_conntrack/' extra_playbooks/roles/kubernetes/node/tasks/main.yml

$ sed -i 's/nf_conntrack_ipv4/nf_conntrack/' roles/kubernetes/node/tasks/main.yml

 

(3) Istio 설치 명령어 수정

아래 두개 파일에 잘못된 문자가 있는데 맨 뒤에 å 를 a 로 고쳐줘야 합니다.

curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.11.4 TARGET_ARCH=x86_64 sh -å

$ sed -i 's/å/a/' extra_playbooks/roles/paasta-cp/istio/tasks/main.yml

$ sed -i 's/å/a/' roles/paasta-cp/istio/tasks/main.yml

 

3) 설치 및 확인

설치 스크립트를 실행해 설치를 진행합니다.

$ bash deploy-cp-cluster.sh

 

아래는 설치중 출력되는 에러 메세지 입니다.

에러가 발생하면 무시가 되면서 설치가 계속 진행됩니다.

혹시 방화벽 룰이 설정된 경우, 설치가 제대로 이루어지지 않거나 설치과정에서 멈추는 경우가 있으니 설치가 잘 되지 않는 분은 방화벽을 잠시 내리고 설치해보는 것도 좋습니다.

 

TASK [etcd : Get currently-deployed etcd version] **************
fatal: [master]: FAILED! => {"changed": false, "cmd": "/usr/local/bin/etcd --version", "msg": "[Errno 2] No such file or directory: b'/usr/local/bin/etcd'", "rc": 2, "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
...ignoring

TASK [kubernetes/control-plane : Check which kube-control nodes are already members of the cluster] **************
fatal: [master]: FAILED! => {"changed": false, "cmd": ["/usr/local/bin/kubectl", "get", "nodes", "--selector=node-role.kubernetes.io/control-plane", "-o", "json"], "delta": "0:00:00.046634", "end": "2023-07-20 23:35:05.782368", "msg": "non-zero return code", "rc": 1, "start": "2023-07-20 23:35:05.735734", "stderr": "The connection to the server localhost:8080 was refused - did you specify the right host or port?", "stderr_lines": ["The connection to the server localhost:8080 was refused - did you specify the right host or port?"], "stdout": "", "stdout_lines": []}
...ignoring

 

TASK [network_plugin/calico : Calico | Get existing FelixConfiguration] *************
fatal: [master]: FAILED! => {"changed": false, "cmd": ["/usr/local/bin/calicoctl.sh", "get", "felixconfig", "default", "-o", "json"], "delta": "0:00:00.060760", "end": "2023-07-24 05:55:32.486934", "msg": "non-zero return code", "rc": 1, "start": "2023-07-24 05:55:32.426174", "stderr": "resource does not exist: FelixConfiguration(default) with error: felixconfigurations.crd.projectcalico.org \"default\" not found", "stderr_lines": ["resource does not exist: FelixConfiguration(default) with error: felixconfigurations.crd.projectcalico.org \"default\" not found"], "stdout": "null", "stdout_lines": ["null"]}
...ignoring


TASK [network_plugin/calico : Calico | Get existing calico network pool] **************
fatal: [master]: FAILED! => {"changed": false, "cmd": ["/usr/local/bin/calicoctl.sh", "get", "ippool", "default-pool", "-o", "json"], "delta": "0:00:00.042520", "end": "2023-07-20 23:36:36.320521", "msg": "non-zero return code", "rc": 1, "start": "2023-07-20 23:36:36.278001", "stderr": "resource does not exist: IPPool(default-pool) with error: ippools.crd.projectcalico.org \"default-pool\" not found", "stderr_lines": ["resource does not exist: IPPool(default-pool) with error: ippools.crd.projectcalico.org \"default-pool\" not found"], "stdout": "null", "stdout_lines": ["null"]}
...ignoring

TASK [network_plugin/calico : Calico | Get existing BGP Configuration] ***************
fatal: [master]: FAILED! => {"changed": false, "cmd": ["/usr/local/bin/calicoctl.sh", "get", "bgpconfig", "default", "-o", "json"], "delta": "0:00:00.034705", "end": "2023-07-20 23:36:37.450199", "msg": "non-zero return code", "rc": 1, "start": "2023-07-20 23:36:37.415494", "stderr": "resource does not exist: BGPConfiguration(default) with error: bgpconfigurations.crd.projectcalico.org \"default\" not found", "stderr_lines": ["resource does not exist: BGPConfiguration(default) with error: bgpconfigurations.crd.projectcalico.org \"default\" not found"], "stdout": "null", "stdout_lines": ["null"]}
...ignoring

TASK [kubernetes-apps/ansible : Kubernetes Apps | Register coredns deployment annotation `createdby`] ***************
fatal: [master]: FAILED! => {"changed": false, "cmd": ["/usr/local/bin/kubectl", "--kubeconfig", "/etc/kubernetes/admin.conf", "get", "deploy", "-n", "kube-system", "coredns", "-o", "jsonpath={ .spec.template.metadata.annotations.createdby }"], "delta": "0:00:00.059931", "end": "2023-07-20 23:37:11.974466", "msg": "non-zero return code", "rc": 1, "start": "2023-07-20 23:37:11.914535", "stderr": "Error from server (NotFound): deployments.apps \"coredns\" not found", "stderr_lines": ["Error from server (NotFound): deployments.apps \"coredns\" not found"], "stdout": "", "stdout_lines": []}
...ignoring

TASK [kubernetes-apps/ansible : Kubernetes Apps | Register coredns service annotation `createdby`] *****************
fatal: [master]: FAILED! => {"changed": false, "cmd": ["/usr/local/bin/kubectl", "--kubeconfig", "/etc/kubernetes/admin.conf", "get", "svc", "-n", "kube-system", "coredns", "-o", "jsonpath={ .metadata.annotations.createdby }"], "delta": "0:00:00.061244", "end": "2023-07-20 23:37:12.300058", "msg": "non-zero return code", "rc": 1, "start": "2023-07-20 23:37:12.238814", "stderr": "Error from server (NotFound): services \"coredns\" not found", "stderr_lines": ["Error from server (NotFound): services \"coredns\" not found"], "stdout": "", "stdout_lines": []}
...ignoring

 

에러가 발생해도 자동으로 넘어가면서 설치가 완료되었습니다. 설치가 잘 되었는지 확인합니다.

$ kubectl get nodes
NAME      STATUS   ROLES           AGE   VERSION
master    Ready    control-plane   16m   v1.25.6
worker1   Ready    <none>          15m   v1.25.6
worker2   Ready    <none>          15m   v1.25.6
worker3   Ready    <none>          15m   v1.25.6

 

$ kubectl get pods -n kube-system
NAME                                       READY   STATUS    RESTARTS      AGE
calico-kube-controllers-75748cc9fd-5k46h   1/1     Running   0             16m
calico-node-7ldrx                          1/1     Running   0             16m
calico-node-f48sv                          1/1     Running   0             16m
calico-node-nxspr                          1/1     Running   0             16m
calico-node-zb9c2                          1/1     Running   0             16m
coredns-588bb58b94-2bbtm                   1/1     Running   0             15m
coredns-588bb58b94-5prkj                   1/1     Running   0             15m
dns-autoscaler-5b9959d7fc-6qzsr            1/1     Running   0             15m
kube-apiserver-master                      1/1     Running   1             17m
kube-controller-manager-master             1/1     Running   2 (14m ago)   17m
kube-proxy-89x74                           1/1     Running   0             16m
kube-proxy-8nfnp                           1/1     Running   0             16m
kube-proxy-bt478                           1/1     Running   0             16m
kube-proxy-v8hjh                           1/1     Running   0             16m
kube-scheduler-master                      1/1     Running   2 (14m ago)   17m
metrics-server-64c4c5ddbc-t6qq5            1/1     Running   0             15m
nginx-proxy-worker1                        1/1     Running   0             16m
nginx-proxy-worker2                        1/1     Running   0             16m
nginx-proxy-worker3                        1/1     Running   0             16m
nodelocaldns-74st7                         1/1     Running   0             15m
nodelocaldns-9dk9v                         1/1     Running   0             15m
nodelocaldns-c2d5f                         1/1     Running   0             15m
nodelocaldns-rv6cf                         1/1     Running   0             15m

 

설치 또는 실행이 중지된 Pod 가 있는지 확인합니다.

아무런 결과가 나오지 않아야 합니다.

$ kubectl get pods -A |grep Pending
The connection to the server 127.0.0.1:6443 was refused - did you specify the right host or port?

이와 같은 메세지가 출력될 경우 조금 기다렸다가 다시 확인해보세요. 클러스터 구성이 모두 정상 가동되려면 약간의 시간이 필요합니다.

 

* 참고 : Kubespray 삭제

$ bash reset-cp-cluster.sh

...

Are you sure you want to reset cluster state? Type 'yes' to reset your cluster. [no]: yes

...

그리고 NFS 서버 공유 디렉토리에 있던 데이터를 모두 지워줍니다.

(NFS 서버에서)

# rm -rf /data/*

 

 

2. 컨테이너 플랫폼 포털 설치

 

컨테이너 플랫폼 포털 (대시보드) 을 이용해 관리자 및 이용자가 쉽게 응용프로그램 등을 생성하고 관리할 수 있습니다.

설치 방법을 알아봅니다.

 

1) 컨테이너 플랫폼 포털 Deployment 파일 다운로드

(Master 노드에서)

포털 배포 파일 다운로드 경로를 생성합니다.
$ mkdir -p ~/workspace/container-platform
$ cd ~/workspace/container-platform

포털 배포 파일을 다운로드하고 압축을 해제합니다.
$ wget --content-disposition https://nextcloud.paas-ta.org/index.php/s/WtNQn2agk6epFHC/download
$ tar xvzf cp-portal-deployment-v1.4.0.tar.gz

* 참고 : Deployment 파일 디렉토리 구성
├── script                # 컨테이너 플랫폼 포털 배포 관련 변수 및 스크립트 파일 위치
├── images             # 컨테이너 플랫폼 포털 이미지 파일 위치
├── charts               # 컨테이너 플랫폼 포털 Helm Charts 파일 위치
├── values_orig      # 컨테이너 플랫폼 포털 Helm Charts values.yaml 파일 위치
└── keycloak_orig   # 컨테이너 플랫폼 포털 사용자 인증 관리를 위한 Keycloak 배포 관련 파일 위치

2) 컨테이너 플랫폼 포털 변수 정의

$ cd cp-portal-deployment/script

$ vi cp-portal-vars.sh

# COMMON VARIABLE (Please change the values of the four variables below.)
K8S_MASTER_NODE_IP="115.68.142.67"            # Kubernetes master 서버의 공인 IP
HOST_CLUSTER_IAAS_TYPE="OPENSTACK"    # Host cluster IaaS type ('AWS' or 'OPENSTACK')
PROVIDER_TYPE="standalone"                            # Container Platform Portal Provider Type ('standalone' or 'service')

...

 

3) 컨테이너 플랫폼 포털 설치

설치를 하기 전에 root 사용자로 변경합니다.

설치를 반복해보니 컨테이너 플랫폼 포털은 root 사용자로 설치가 잘 되는것을 확인했습니다.

$ sudo su -

# cd /home/ubuntu/workspace/container-platform/cp-portal-deployment/script

 

파일에 실행권한을 주고 실행합니다.

# chmod +x deploy-cp-portal.sh

# ./deploy-cp-portal.sh 

 

컨테이너 플랫폼 포털 관련 리소스가 정상적으로 배포되었는지 확인합니다.
리소스 Pod 의 경우 Node 에 바인딩 및 컨테이너 생성 후 Error 또는 Pending 상태에서 시간이 지나 Running 상태로 전환되기도 하므로 시간을 갖고 기다려봅니다.

 

Harbor 리소스 조회

# kubectl get all -n harbor

>> 정상

 

MariaDB 리소스 조회

# kubectl get all -n mariadb

>> 정상

 

Keycloak 리소스 조회

# kubectl get all -n keycloak

>> 정상

 

컨테이너 플랫폼 포털 리소스 조회

# kubectl get all -n cp-portal

>> 정상

 

혹시 설치가 잘 안되는 경우 아래 '컨테이너 플랫폼 포털 리소스 삭제' 방법대로 설치된 파일을 삭제한 다음에, deploy-cp-portal.sh 설치 스크립트 파일의 내용을 부분적으로 실행해 서 에러 원인을 찾고 조치하면 문제가 되는 부분이 어디인지 확인을 할 수 있습니다.

 

4) 컨테이너 플랫폼 포털 접속

컨테이너 플랫폼 포털은 아래 주소와 같이 Master node 의 IP 와 포트 32703 으로 접속 가능합니다.

보안 강화를 위해 로그인 후 제일 먼저 패스워드 변경하는 것이 좋습니다.

http://115.68.142.67:32703

ID : admin

PW : admin

 

Harbor 오픈 소스 컨테이너 이미지 레지스트리의 대시보드 URL 과 기본 계정입니다.

이것도 마찬가지로 처음 로그인 후 패스워드를 변경하는 것이 좋습니다.

http://115.68.142.84:30002

ID : admin

PW : Harbor12345

 

Keycloak 소스 싱글 사인온 (Single Sign-On, SSO) 솔루션 대시보드 URL 과 기본 계정입니다.

http://115.68.142.84:32710

ID : admin

PW : admin

 

* 참고 : 컨테이너 플랫폼 포털 리소스 삭제

# chmod +x uninstall-cp-portal.sh
# ./uninstall-cp-portal.sh

Are you sure you want to delete the container platform portal? <y/n> y

...

# sudo rm -rf ../keycloak

 

반응형

댓글()