플러터에는 View Widget으로 크게 4종류가 있다 

PageView, ListView, GridView, TapbarView, 

 

하나하나씩 살펴보자 

 

PageView는 아래 사진과 같이 슬라이드 형식으로 애니매이션이 들어가 있는 뷰이다 

 

코드로  예제를 살펴보면 다음과 같이 나타낼수 있다. 

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: PageView(
        children: [
          Container(
            color: Colors.red,
            child: const Center(
              child: Text(
                "1",
                style: TextStyle(fontSize: 50, color: Colors.white),
              ),
            ),
          ),
          Container(
            color: Colors.blue,
            child: const Center(
              child: Text(
                "2",
                style: TextStyle(fontSize: 50, color: Colors.white),
              ),
            ),
          ),
          Container(
            color: Colors.yellow,
            child: const Center(
              child: Text(
                "3",
                style: TextStyle(fontSize: 50, color: Colors.white),
              ),
            ),
          ),
        ],
      )),
    );
  }
}

Body안에 PageView를 생성하고 children으로 요소를 설정해 주면 저 위에 사진처럼 동작하는 View를 만들 수 있다, 

다양한 옵션은 덤, 여러 유용한 옵션이 있으니 구글에 찾아볼 수 있도록 하자 


 

ListView같은 경우에는  아래 사진과 같이 말그대로 여러 리스트를 한페이지에서 보여주는 View라고 할 수 있다

샘플코드는 다음과 같다 

Body에서 ListViewf를 설정해주고 똑같이 children으로 요소를 받아서 프린트 하는 식이다

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: ListView(
          scrollDirection: Axis.horizontal,
          children: List.generate(
            10,
            (index) => Container(
              width: 100,
              height: 100,
              margin: const EdgeInsets.all(5),
              color: Colors.red.withAlpha((index + 1) * 25),
            ),
          ),
        ),
      ),
    );
  }
}

 

유용한 옵션중 하나인 reverse는 true로 주게 되면 제일 첫번째 요소가 axis의 제일 마지막에 위치하게 된다 

또한 Physics옵션도 있는데 컨트롤러를 연결하고 사용하면 된다고 한다 


다음으로는 GridView 이다 

GridView는 다음과 같이 N * N 의 요소를 표현할때 사용하면 좋다 

코드로는 아래와 같이 역시 GridView로 정의 하고 사용하는 모습을 볼수 있다. 

주의 해야할 점은 gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount 옵션을 필수로 들어가야 하고 

crossAxisCount가 그 축에서 나타낼 요소의 수를 나타낸다고 보면 된다. 나머지 옵션은 spacing, 즉 얼마나 띄어서 요소를 나타낼건지

결정한다고 보면 된다. 

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return  MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: GridView(
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 3,
            mainAxisSpacing: 2,
            crossAxisSpacing: 2,
          ),
          children: List.generate(
            100,
            (index) => Center(
              child: Container(
                color: Colors.grey,
                child: Center(child: Text(index.toString())),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

 

또한 다른 옵션도 있는데 아래와 같ㅌ이 옵션을 주게 되면

각 요소가 최대 얼마나 길이를 가지고 있을수 있는지 정해주는 옵션이다. 

          gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
            maxCrossAxisExtent: 300,
            mainAxisSpacing: 2,
            crossAxisSpacing: 2,
          ),

마지막 요소인 TabBarView 이다 

말그대로 상단 혹은 하단에 위치하면서 다른 탭을 나타낼때 사용하면 된다. 

 

 

TabBarView는 다른 View와는 다르게 2가지 요소로 구성이 되는데 

말 그대로 Tab을 나타내는 요소와 Body를 나타내는 요소 2가지로 나누어지게 된다. 

 

코드를 살펴보자 

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(body: const SampleWidget()),
    );
  }
}

class SampleWidget extends StatefulWidget {
  const SampleWidget({super.key});

  @override
  State<SampleWidget> createState() => _SampleWidgetState();
}

class _SampleWidgetState extends State<SampleWidget>
    with TickerProviderStateMixin {
  late TabController _tabController;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(
      length: 3,
      vsync: this,
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          TabBar(
            controller: _tabController,
            labelColor: Colors.blue,
            unselectedLabelColor: Colors.grey,
            labelPadding: const EdgeInsets.symmetric(vertical: 20),
            tabs: const [
              Text('메뉴1'),
              Text('메뉴2'),
              Text('메뉴3'),
            ],
          ),
          Expanded(
            child: TabBarView(
              controller: _tabController,
              children: [
                Container(
                  color: Colors.blue,
                  child: Center(child: Text('메뉴1 페이지 ')),
                ),
                Container(
                  color: Colors.blue,
                  child: Center(child: Text('메뉴2 페이지 ')),
                ),
                Container(
                  color: Colors.blue,
                  child: Center(child: Text('메뉴3 페이지 ')),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

 

양이 좀 많지만 어렵지 않다. 

 

SampleWidget은 StatefulWidget을 상속받아 State를 유지하게 된다. 

그리고 컨트롤러가 중요하다! TabController를 late로 선언하고 initState()에서 초기화 해야 한다 

vsync는 this를 사용하기 위해 with TickerProviderStateMixin을 같이 선언해준다

(with ~는 animation을 사용할 경우 항상 사용해야 한다고 한다[싱크맞추기위해])

 

Tabbar의 메뉴개수와 아래 body에서 페이지 개수는 같아야한다, 다르면 오류가 난다 

 

Body는 Contoller를 반드시 넣어줘야 한다는걸 잊지말자

페이지를 나타낼때는 Expanded로 선ㅇ넌하고 아래 컨트롤러를 정하고 내용을 넣어주면 된다

 

Tab은 아래와 같이 옵션을 정할수 있다

TabBar(
  controller: _tabController,
  labelColor: Colors.blue,
  unselectedLabelColor: Colors.grey,
  labelPadding: const EdgeInsets.symmetric(vertical: 20),
  tabs: const [
    Text('메뉴1'),
    Text('메뉴2'),
    Text('메뉴3'),
  ],
),

 

 

 

팀 스파르타에서 운영하는 내일배움캠프중 하나인 플러터 앱창업 5기를 등록하고 241021부로 수업이 시작되었다

 

TIL과 WIL를 위해 기록을 남겨야 하기 때문에 오랜만에 글을 작성하게 되었다..

 

글쓰는게 어색하고 적응이 안된다. 

 

배운건 많은데 그걸 다 적기엔 시간이 오래 걸릴거 같기도 하고

 

일단 필요한것만 적어보자 

시간은 없고 내용은 많으니 TL;DR 하겠습니다

 

결론
1. 실제로 프로덕트 환경에서는 안쓰일거같다 왜냐하면 컨테이너 개발이 상당히 어려울거같기 떄문..

 

반박 시 님들말이 맞습니다. ㅎㅎ 

 

이번에는 폐쇄망 환경에서 윈도우즈 2019 서버를 클러스터에 노드로 추가해보겠습니다. 

 

개념은 온라인 설치와 똑같습니다 

 

CalicoNode와 CalicoFelix 서비스를 설치한 뒤 Kubelet과 Kube-proxy를 설치하면 클러스터에 붙습니다. 

 

대신 폐쇄망이므로 온라인설치에 필요한 모든 파일을 사전에 다운로드 받아 노드로 추가할 윈도우즈 서버에 옮겨야 합니다. 

 

시작해보겠습니다

 

필요 파일 리스트 
* 7zip.msi (압축풀기용으로 필요)

(https://www.7-zip.org/download.html)
* Containers 설치 파일

(https://github.com/containerd/containerd/blob/main/docs/getting-started.md 에서 Windows검색하여 최신버전 받을 수 있음)
* calico-windows(v3.27.0버전 사용)

(https://docs.tigera.io/calico/latest/getting-started/kubernetes/windows-calico/manual-install/standard 에서 최신버전의 Calico 설치 스크립트를 받을 수 있습니다)
* kubernetes-node-windows-amd64(k8s 요소 설치 관련)


* helper.psm1, helper.psm1, hns.psm1(calico install script에서 필요 모듈 파일)

(helperv2 -> https://raw.githubusercontent.com/Microsoft/SDN/master/Kubernetes/windows/helper.v2.psm1

helper -> https://raw.githubusercontent.com/Microsoft/SDN/master/Kubernetes/windows/helper.psm1

hns -> https://github.com/microsoft/SDN/blob/master/Kubernetes/windows/hns.psm1  )

 

* install-calico-windows.ps1(calico install 스크립트)
(https://github.com/projectcalico/calico/blob/master/node/windows-packaging/install-calico-windows.ps1)


* kube config 파일 (calico 설치시 필요)

(마스터의 ~/.kube/config 파일입니다.)

 

위 파일들을 모두 받아 윈도우즈 서버 C:\k 디렉토리로 옮겨둡니다(k 디렉토리가 없으면 생성해줍니다). 

 

사전작업

    1. HNS 서비스 활성화 하기 

Install-WindowsFeature -Name containers
Restart-Computer -Force

위 명령어를 윈도우 powershell에 입력하여 HNS서비스를 활성해 좁니다. 

(인터넷 없어도 실행됩니다)

 

    2. 2개 폴더를 생성해 줍니다. 

mkdir "C:\Program Files\containerd\cni\bin"
mkdir "C:\k"

해당 폴더가 자동으로 생성되지 않으므로 사전에 생성해둠
“C:\k” 폴더는 calico설치시 사용되는 폴더이므로 인터넷에서 받은 파일을 넣어줍니다

 

본작업

 

    1. 7zip.msi를 설치해 줍니다

    2. ContainerD 설치

# *인터넷필요*
# 인터넷에서 해당 파일을 받고 폐쇄망 서버로 옮긴다. 이 단계 이후 설치 방법은 내용을 참조
# [ContainerD버전]를 받은 버전으로 수정한다 
curl.exe -L https://github.com/containerd/containerd/releases/download/v[ContainerD버전]/containerd-[ContainerD버전]-windows-amd64.tar.gz -o containerd-windows-amd64.tar.gz
tar.exe xvf .\containerd-windows-amd64.tar.gz
#____________________________________________________

# Copy and configure
Copy-Item -Path ".\bin" -Destination "$Env:ProgramFiles\containerd" -Recurse -Container:$false -Force
cd $Env:ProgramFiles\containerd\
.\containerd.exe config default | Out-File config.toml -Encoding ascii

# Review the configuration. Depending on setup you may want to adjust:
# - the sandbox_image (Kubernetes pause image)
# - cni bin_dir and conf_dir locations
Get-Content config.toml

# Register and start service
.\containerd.exe --register-service
Start-Service containerd

 

    3. Calico 설치 

        1. Install-calico-windows.ps1 스크립트를 참조하여 인터넷으로 다운로드 받는 파일들을 미리 폐쇄망에 옮겨놓는다 

           -> Line 48, 49, 54, 56, 주석처리한다 [스크립트에 인터넷을 사용하여 다운로드 하는 코드를 주석처리 한다]

           -> 스크립트 처음 Param부분에서 $RelaseFile, $KubeVersion, $ServiceCidr, $DNSServerIPs를 알맞게 수정
         

        2. kubectl 파일 미리 받아둠 - 7zipFM으로 압축풀기 (인스톨스크립트에서 인터넷에서 소스땡겨오는부분 주석처리)
           -> kubernetes-node-windows-amd64.tar 파일을 7zip으로 압축풀어 내용물을 k 폴더에 넣어놓는다

 

        3.  k8s마스터 노드의 /root/.kube/config 파일 k 폴더로 옮기기

        4. calico-windows.zip 파일을 C:\로 옮긴다

        5. Install-calico-windows.ps1 스크립트를 실행한다

        6. CalicoNode, CalicoFelix 서비스가 정상적으로 실행되는지 확인한다

            [Get-Service 명령어 사용]

 

    4. Calico 설치 이후 C:\CalicoWindows\Kubernetes 내부 install-kube-services.ps1 스크립트를 실행하여 Kubelet, kube-proxy 설치 후 실행까지 확인

    5. K8s Master에서 Windows노드가 정상적으로 추가되었는지 확인

 

아쉽게도 아직 윈도우 노드와 빌드가 맞게 생성된 pod이 없어서 pod이 올라가는지 테스트는 못해봤지만 노드가 정상적으로 추가되는것을 확인했습니다. 

 

궁금하시거나 이상하다 하시는점 있으시면 알려주세요!

시간은 없고 내용은 많으니 TL;DR 하겠습니다 

 

결론
1. 윈도우즈 노드가 추가되는 시점부터 특정 서비스 사용이 강제된다
   -> 기존 환경과 다를경우 다시 서비스를 구성해야 할수도 있다 
2. 윈도우즈 노드의 k8s 업데이트는 현재 방법이 없다. K8s 업데이트시 다시 설치해야한다. 
3. 윈도우즈 컨테이너를 빌딩할 때 현재 사용중인 노드의 빌드와 맞게 구성해야하므로 윈도우즈 업데이트에 제약이 생긴다

 

제가 설치 및 자료 찾아보면서 느낀 결과이니 반박 시 님들말이 맞습니다ㅎㅎ

 

*2024년 2월 부로 윈도우즈 서버 노드 추가시 제약사항

* 윈도우즈 서버로 컨트롤플레인 구성 불가
* 윈도우 특정 버전만 지원(2019, 2022)
* 윈도우 컨테이너가 리눅스 컨테이너와 함께 동작하지 않음
* 윈도우에서 볼륨 마운트 옵션을 지원하지 않음
* 윈도우에서는 호스트 네트워크 모드를 지원하지 않음

 

사전 체크 사항 
* 유휴 윈도우즈 서버 버전 체크
  - 윈도우즈 서버 버전 체크 (2019, 2022만 가능)
* Host OS 버전이 배포할 Container OS 버전과 일치해야 한다
(예를들어 Node가 2019.17763이면 안의 컨테이너도 2019.17763버전 이어야한다)
* 윈도우즈 업데이트 설치 확인
  - 2019 Server기준 **KB4489899 업데이트 이후 버전이 설치되어있으면 됨.**
* Calico의 Overlay모드를 사용할때 IPIP모드는 지원하지 않는다. 따라서 VXLAN모드로 변경하여 사용해야 한다

 

  윈도우 리눅스
컨테이너 런타임 여러 런타임 지원 ContainerD
리소스 Isolation Cgroups 프로세스 및 Namespace Isolation
Network 기존 네트워크 사용 Host Networking Service(HNS)사용
컨테이너 가벼운용량, 쉬운 컨테이너 개발 무거운 용량, 상대적으로 어려운 컨테이너개발
네트워크 여러 Networking Plugin 사용가능  Calico 혹은 Flannel

 

클러스터 사전작업

    1. 윈도우즈 업데이트 확인

    2. Master Node 에서 CalicoCTL 설치 

        1. curl -O -L https://github.com/projectcalico/calicoctl/releases/download/v3.17.1/calicoctl
        2. chmod +x calicoctl
        3. sudo mv calicoctl /usr/local/bin

    3. IPIP를 VXLAN모드로 변경

calicoctl get ippool default-ipv4-ippool -o wide
calicoctl get ippool default-ipv4-ippool -o yaml | sed -e "s/ipipMode: Always/ipipMode: Never/" | calicoctl apply -f -
calicoctl get ippool default-ipv4-ippool -o yaml | sed -e "s/vxlanMode: Never/vxlanMode: Always/" | calicoctl apply -f -
calicoctl get ippool default-ipv4-ippool -o wide

    4. IPAM 옵션 수정

calicoctl ipam configure --strictaffinity=true

 

    5. 디렉토리 생성 및 Config 복사

       

(윈도우즈 서버에서) mkdir c:\k
(윈도우즈 powershell에서) scp root@[마스터서버]:~/.kube/config c:\k\

참고로 만약 권한 없음으로 scp 가 되지 않을경우 config파일을 일반 유저 권한으로 변경 후 scp 를 실행한다 

 

 

인터넷망에서 윈도우즈 서버 노드 추가방법 - 본 작업

 

모든 작업은 추가하고자 하는 윈도우즈 서버에서 작업한다 

 

    1. ContainerD 설치

Invoke-WebRequest -UseBasicParsing "https://raw.githubusercontent.com/microsoft/Windows-Containers/Main/helpful_tools/Install-ContainerdRuntime/install-containerd-runtime.ps1" -o install-containerd-runtime.ps1

.\install-containerd-runtime.ps1

 

    2. Calico Component 설치 및 구동

Invoke-WebRequest -Uri https://github.com/projectcalico/calico/releases/download/v3.27.0/install-calico-windows.ps1 -OutFile c:\k\install-calico-windows.ps1

    (*Calico 버전은 수정될 수 있다)

c:\k\install-calico-windows.ps1 -ReleaseBaseURL "https://github.com/projectcalico/calico/releases/download/v3.27.0" -ReleaseFile "calico-windows-v3.27.0.zip" -KubeVersion "1.28.2" -DownloadOnly "yes" -ServiceCidr "10.96.0.0/12" -DNSServerIPs "10.96.0.10"

 

    (*Calico 버전은 수정될 수 있다.)

    (* KubeVersion은 현재 클러스터에 설치된 K8s 버전이다)

    (* ServiceCidr과 DNSServerIPs는 클러스터의 Master서버에서 kubectl cluster-info dump > dump.log 명령어 실행후                   dump.log파일을 확인하여 찾을 수 있다 )

 

    환경변수 설정

$ENV:CNI_BIN_DIR="c:\program files\containerd\cni\bin" 
$ENV:CNI_CONF_DIR="c:\program files\containerd\cni\conf" 
c:\calicowindows\install-calico.ps1
c:\calicowindows\start-calico.ps1

 

    Service 실행

Start-Service CalicoFelix
Start-Service CalicoNode
Get-Service CalicoFelix
Get-Service CalicoNode

-> 각각 Running 상태이면 된다

 

    3. 쿠버네티스 컴포넌트 설치 및 구동

c:\calicowindows\kubernetes\install-kube-services.ps1

Start-Service kubelet 
Start-Service kube-proxy
Get-Service Kubelet
Get-Service kube-proxy

-> 각각 Running 상태이면 된다

New-NetFirewallRule -Name 'Kubelet-In-TCP' -DisplayName 'Kubelet (node)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 10250
(* 위 명령어는 방화벽이 막혀있을때 사용하면 된다)

 

설치는 간단하게 이것으로 끝이다.  실제로 Pod까지 띄울수 있는지 확인해 보자 

 

다음과 YAML을 작성 후 마스터노드에서 실행해보자 

---
apiVersion: v1
kind: Service
metadata:
  name: win-webserver
  labels:
    app: win-webserver
spec:
  ports:
    # the port that this service should serve on
    - port: 80
      targetPort: 80
  selector:
    app: win-webserver
  type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: win-webserver
  name: win-webserver
spec:
  replicas: 2
  selector:
    matchLabels:
      app: win-webserver
  template:
    metadata:
      labels:
        app: win-webserver
      name: win-webserver
    spec:
     containers:
      - name: windowswebserver
        image: mcr.microsoft.com/windows/servercore:ltsc2019
        command:
        - powershell.exe
        - -command
        - "<#code used from https://gist.github.com/19WAS85/5424431#> ; $$listener = New-Object System.Net.HttpListener ; $$listener.Prefixes.Add('http://*:80/') ; $$listener.Start() ; $$callerCounts = @{} ; Write-Host('Listening at http://*:80/') ; while ($$listener.IsListening) { ;$$context = $$listener.GetContext() ;$$requestUrl = $$context.Request.Url ;$$clientIP = $$context.Request.RemoteEndPoint.Address ;$$response = $$context.Response ;Write-Host '' ;Write-Host('> {0}' -f $$requestUrl) ;  ;$$count = 1 ;$$k=$$callerCounts.Get_Item($$clientIP) ;if ($$k -ne $$null) { $$count += $$k } ;$$callerCounts.Set_Item($$clientIP, $$count) ;$$ip=(Get-NetAdapter | Get-NetIpAddress); $$header='<html><body><H1>Windows Container Web Server</H1>' ;$$callerCountsString='' ;$$callerCounts.Keys | % { $$callerCountsString+='<p>IP {0} callerCount {1} ' -f $$ip[1].IPAddress,$$callerCounts.Item($$_) } ;$$footer='</body></html>' ;$$content='{0}{1}{2}' -f $$header,$$callerCountsString,$$footer ;Write-Output $$content ;$$buffer = [System.Text.Encoding]::UTF8.GetBytes($$content) ;$$response.ContentLength64 = $$buffer.Length ;$$response.OutputStream.Write($$buffer, 0, $$buffer.Length) ;$$response.Close() ;$$responseStatus = $$response.StatusCode ;Write-Host('< {0}' -f $$responseStatus)  } ; "
     nodeSelector:
      kubernetes.io/os: windows

 

사진으로 찍진 못했지만 윈도우즈 노드로 Pod이 배치되었을 것이다. 

'Docker & K8s' 카테고리의 다른 글

Windows 2019 폐쇄망 K8s(Kubernetes) 노드 추가 방법  (0) 2024.02.13
ubuntu 20.04 K8s 설치 노트  (0) 2024.01.08

OpenStack에서 Ubuntu 20.04위에 Multi-cluster k8s설치 기록입니다

 

1. 도커 설치 

sudo apt-get update
 
sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

sudo systemctl enable docker
sudo systemctl start docker

 

1.1 설치 이후 containerd설정파일을 수정

vim /etc/containerd/config.toml

이부분을 주석처리 해준다
#disable_plugins = ["cri"]

containerd 재시작

systemctl stop containerd
systemctl start containerd

 

2. K8s 설치

#swap영역을 꺼준다
swapoff -a && sed -i '/swap/s/^/#/' /etc/fstab
#ubuntu 20.04에서는 기본적으로 keyrings폴더가 없어서 다르게 설정함
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://dl.k8s.io/apt/doc/apt-key.gpg
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update -y
#k8s 설치 및 버전 홀드 명령어
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

#설치 후 환경설정
 mkdir -p $HOME/.kube
 sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
 sudo chown $(id -u):$(id -g) $HOME/.kube/config

 export KUBECONFIG=/etc/kubernetes/admin.conf

 

3. K8s control-plane 설정

 

sudo kubeadm init --control-plane-endpoint [controlplane IP]:6443 --upload-certs

#이후 다음과같은 URL들이 생성됨

kubeadm join 10.10.10.46:6443 --token ygmu0q.07f8v7xz3ghq6k1t \
	--discovery-token-ca-cert-hash sha256:f16a98dbc6fedbe229f57ba2c8bf531623be8ca8d0f536afb3e363a3ca14f527 \
	--control-plane --certificate-key 3964d2b0dc528a3c2000d51383aa2825197305d31ab935a92069741628e1ca8d
#위 URL은 join할 control-plane node에서 실행해 주면 됨

kubeadm join 10.10.10.46:6443 --token nf8qv9.g3iu91lv102w17yt --discovery-token-ca-cert-hash sha256:f16a98dbc6fedbe229f57ba2c8bf531623be8ca8d0f536afb3e363a3ca14f527
#위 URL은 join할 worker-node 에서 실행해 주면 됨

 

만약 url을 잃어버렸을경우 재 발급 방법

#일반 node join문 재 출력 명령어
kubeadm token create --print-join-command

#Control-plane join문 재 출력 
echo $(kubeadm token create --print-join-command) --control-plane --certificate-key $(kubeadm init phase upload-certs --upload-certs | grep -vw -e certificate -e Namespace)

 

4. Calico 설치

kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
#시간좀 지난뒤 Pod 생성 및 구동 확인

kubectl get pods -A

NAMESPACE     NAME                                       READY   STATUS              RESTARTS      AGE
kube-system   calico-kube-controllers-7ddc4f45bc-vhsxq   0/1     ContainerCreating   0             17s
kube-system   calico-node-4rwvz                          0/1     Init:2/3            0             17s
kube-system   calico-node-v7x54                          0/1     Init:2/3            0             17s
kube-system   coredns-5dd5756b68-7q2vm                   0/1     ContainerCreating   0             19m
kube-system   coredns-5dd5756b68-vzr8g                   0/1     ContainerCreating   0             19m
kube-system   etcd-issac-master                          1/1     Running             1             19m
kube-system   etcd-issac-master3                         1/1     Running             0             18m
kube-system   kube-apiserver-issac-master                1/1     Running             1             19m
kube-system   kube-apiserver-issac-master3               1/1     Running             0             18m
kube-system   kube-controller-manager-issac-master       1/1     Running             1 (18m ago)   19m
kube-system   kube-controller-manager-issac-master3      1/1     Running             0             18m
kube-system   kube-proxy-6kd4x                           1/1     Running             0             18m
kube-system   kube-proxy-8f8h9                           1/1     Running             0             19m
kube-system   kube-scheduler-issac-master                1/1     Running             2 (18m ago)   19m
#k8s control-plane node ready상태 확인

kubectl get nodes

root@issac-master:/home/ubuntu# k get nodes
NAME            STATUS   ROLES           AGE   VERSION
issac-master    Ready    control-plane   20m   v1.28.2
issac-master3   Ready    control-plane   18m   v1.28.2

안녕하세요~

이번에 NHN에서 주최하는 클라우드 관련 교육이 있어서 참여하고 기록으로 남기기 위해 후기를 작성합니다!ㅎㅎ 

 

 

교육신청은 NHN Cloud 교육 홈페이지[https://www.nhncloud.com/kr/edu] 에서 "무료"로 신청 가능합니다!

제가 신청한 교육은 "NHN Cloud Hands on Lab 첫걸음" 이라는 과목이였는데요, 

10시부터 17시까지 이루어지는 하루짜리 Basic 코스였습니다

 

신청은 회사계정이 아닌 개인계정으로 신청해야 했습니다, 

그래야 추후 크레딧 지급이 가능하다고 하네요 참고바랍니다

 

제가 신청한 과목 외에도 여러가지 과정이 진행되고 있었습니다 

교육레벨과 교육명을 확인하시고 마음에 드는 과정을 수강하실수 있겠네요!

NHNCloud 교육 과정 리스트

 

교육은 강남에 있는 교육장에서 10시 정각에 딱 시작했습니다!

수강인원은 약 30~40명정도 계셨었습니다. 

 

교육은 체계적으로 진행되었습니다. 

Slido라는 플랫폼과 강사님이 만드신 PPT를 가지고 진행되었는데, 쉽게 따라할 수 있게끔 잘 구성되었습니다 

 

아래 사진과 같이 강사님이 집적 질문 하시면서 NHN Cloud 인프라 구축에 관련된 내용을 설명해주셨습니다

질문으로 생각하게 하면서 내용을 배우니 그냥 듣는 것보다 더 효과적으로 내용을 숙지 할 수 있었습니다. 

교육중 인프라 구축 관련 질문 내용

오늘 배운 내용은 아래와 같은 인프라를 구축하는 것이였는데요, 

Basic의 내용이라고 하기엔 생각보다 복잡했는데요, 

그 만큼 배울것이 많았습니다. 

기본적인 인스턴스 생성부터 오토스케일링, 로드밸런서 생성 및 VPC Peering까지 많은 내용을 Cover하는것을 확인할 수 있습니다. 

Hands on Lab 과정 인프라 구성도

 

세부적인 교육은 Slido 플랫폼을 통해서 Lab별로 강사님이 그때그때 공개를 해주셔서 실습을 진행했습니다 

랩은 약 10개정도 있었습니다. 

각 Lab마다 목표와 수행해야하는 작업이 상세히 사진과 함께 있어서 쉽게 따라갈 수 있었습니다. 

LAB페이지

각 Lab이 진행될때 아래 사진과 같이 Lab을 완료하였는지 Slido 플랫폼을 이용해서 체크하고 

모든 수강생이 작업을 완료해야 다음으로 넘어갔는데요, 

한사람도 놓치지 않겠다는 강사님의 의지가 보였습니다 

Slido로 Lab 완료 과정 체크

아래 사진은 Slido로 오늘 학습한 내용을 체크하고있는 모습인데요, 

Lab 중간중간 배운 내용을 다시 리마인드 할 수 있어서 좋았습니다. 

Slido플랫폼에서 퀴즈

마지막으로 수업마지막에 오늘 하루 배운내용을 WrapUp하면서 퀴즈를 풀어보았는데요, 

이게 매우 재밌는게 맞은 개수와 정답을 체크한 시간으로 수강생들의 순서가 나오더라구요!ㅋㅋ

이 순서에 따라 강사님이 상품을 지급해주셨습니다. 

굿즈가 탐나네요...ㅎㅎ

 

강의를 들으면서 NHN Cloud 에서 교육을 진짜 많이 준비했구나라고 느껴졌습니다

사실 타사의 교육을 들을때는 일방적으로 내용만 알려주시는 교육도 많았는데, 

이번 강의는 집적 구축도 진행하면서 강사님이 집적 도와주셔서 클라우드의 서비스의 전반을 쉽게 흝을수 있는 강의였던 것 같습니다. 

이후에 또 기회가 된다면 다른 강의도 수강하고 싶은 마음이 생기는 강의였습니다!

 

만약 클라우드를 체험해보고 싶으시다면 NHN Cloud 교육 강력 추천드립니다!

 

감사합니다!

 

P.S. FYI, 랩 수강시 NHN Cloud 크레딧 3만원이 계정에 추가되고 약 2달간 사용할 수 있습니다.

이 크레딧으로 여러 서비스들을 체험해 볼수 있습니다!  

이번 포스팅에서는 DB와 서버를 생성해보도록 하겠습니다. 

 

제일 먼저 생성할 자원은 DB입니다 

(CDB for MySQL은 2 vCPU, 4GB RAM 사용시 160원/시간이 청구됩니다)

 

아래 사진과 같이 CDB for MySQL로 이동하여 DB생성을 눌러서 진행합니다. 

CDB for MySQL 생성

 

 

생성을 누르게 되면 아래와 같이 설정을 하는 창이 뜨는데 다음과 같이 입력해주시고 넘어가시면 되겠습니다. 

    - DB 엔진 버전 mysql(8.0.25)

    - 고가용성 지원 체크해제 

    - VPC 및 Subnet(issac-db) 선택

    - DB Server 이름 및 서비스 이름 임의로 설정

DB 생성 창 - 1

DB생성 두번째 창입니다. 이 부분은 실제로 DB접속 정보와 DB를 구성하는 정보를 입력하는 페이지 입니다 

    - User_ID는 DB에 접속할때 사용하는 ID 입니다

    - HOST(IP)는 DB에 접속허용할 IP를 정하는 옵션입니다. 여기서는 모든 IP를 허용하기 위해 '%' 를 입력하였습니다

      (좋은 방법은 아닙니다, 실제에서는 최소한의 권한을 주기위해 WAS IP대역을 주는 것을 권장합니다만,

       연습이니까 그냥 줬습니다)

    - USER 암호는 접속 암호입니다.

    - 기본 DB명은 최초에 생성할 DB명입니다, 여기서 생성할 DB를 Wordpress설치시 사용할것이기 때문에, 기억해주도록        합시다 

DB 생성 창 - 2

이렇게 하시면 DB는 생성완료입니다, 참 쉽죠? ㅋㅋㅋ

 

자 이제 서버 생성입니다 

 

서버는 총 2대(Web, WAS)를 생성할 시간입니다. 

저는 미리 서버를 생성해서 서버2대가 보이지만.. 

Server -> + 서버 생성을 클릭하여 서버 생성창으로 이동합니다.

서버 생성 버튼 클릭

 

서버 생성 첫번째 창입니다. 

저희는 CentOS 7.8버전을 사용하겠습니다

NCP는 서버 용량이 Windows는 100GB, Linux는 50GB로 고정되어 있습니다. 

서버 타입은 제일 저렴한 서버타입이 있는 High CPU를 고르시고 넘어가시면 되겠습니다

(서버는 2 vCPU, 4GB RAM 사용시 100원/시간이 청구됩니다)

서버 생성 - 1

 

서버 생성 2번째 페이지 입니다. 

    - VPC와 Subnet을 알맞게 정하고 

    - 서버 타입은 vCPU 2개 4GB RAM

    - 시간 요금제

    - 서버 이름은 web서버는 wordpress-web, WAS는 wordpress-was, 

    - Network Interface에서 IP를 입력하지 않으시고 추가를 누르시면 자동으로 IP가 할당됩니다 

    - wordpress-web 서버는 새로운 공인IP 할당을 해줍니다. 

서버 생성 - 2

 

서버 생성 세번째 페이지 입니다. 

인증키를 설정하는 페이지 입니다. 

이미 인증키아 있으신분들은 선택하시고 넘어가시고

없으신 분들은 "새로운 인증키 생성"을 통해 인증키를 생성 및 다운로드 하시고 넘어가면 되겠습니다.

(두번째 서버는 보유하고 있는 인증키 이용 하시면 됩니다)

서버 생성 - 3

 

서버 생성 네번째 페이지 입니다 

이전 포스팅에서 생성했던 ACG를 할당하는 페이지 입니다. 

wordpress-web 서버는 issac-pub-acg를 할당하고 넘어가시고

wordpress-was 서버는 issac-pub-pri를 할당하시고 넘어가시면 되겠습니다. 

서버 생성 - 4

 

이로써 서버 생성도 완료되었습니다!

안녕하세요, 이번 포스팅에서는 NCP상에서 3 Tier 구성으로 Wordpress를 구축을 해보는 과정을 보여드리려고 합니다. 

 

긴말하지 않고 보시죠 

 

일단 인터넷에서 말하는 2 Tier와 3 Tier의 차이점은 다음과 같습니다. 

    1.  2 Tier 에서는 클라이언트 서버에서 DB서버로 집적 데이터를 입력하고 불러오는 방식이다

         장점 개발이 편리하다, 개발비용이 저렴하다, 유지보수가 쉽다

         단점 보안에 취약하다, 서버에 부하가 일어나기 쉽다.

    2.  3 Tier 에서는 클라이언트 서버에서 비즈니스 로직을 담당하는 역할을 떼어내 독립된 서버로 만든 구조이다

         장점 보안이 강화된다, 서버의 부하를 줄일 수 있다.

         단점 관리 포인트가 늘어난다, 개발기간이 늘어난다

 

구성은 다음과 같이 차이가 나구요! 

2Tier vs 3Tier

진짜 기초부터 차근차근 만들어 보겠습니다. 

 

일단 NCP에 로그인을 하신뒤 아무것도 없는 가정하에 VPC부터 생성해보겠습니다. 

10.0.0.0/16 대역 VPC 생성

저는 10.0.0.0/16 대역으로 VPC를 생성하였습니다

 

 

다음은 VPC내부에 서브넷 생성입니다. 

 

Subnet 생성

서브넷은 총 3개를 생성합니다, 하나는 Web서버가 할당될 public 서브넷, WAS 전용 private 서브넷, DB전용 private 서브넷,

서브넷 정보는 다음과 같습니다. 

Subnet 이름  IP 주소  internet Gateway 전용 여부 용도
issac-db 10.0.2.0/24 N(Private) 일반
issac-pri 10.0.1.0/24 N(Private) 일반
issac-pub 10.0.0.0/24 Y(Public) 일반

 

다음은 Private Subnet에서 만들어지는 WAS서버에서 Yum으로 프로그램 설치를 위한 NAT Gateway 생성 및 Route Table 설정입니다. 

Nat Gateway 생성

 

Route table은 AWS에서와는 조금 다르게 default Private route table 에 집적 걸어줍니다!

Route Table 설정
Route Table&nbsp; 내용 추가

다음은 서버에 적용할 ACG를 생성해보겠습니다.

(본 포스팅에서는 NACL은 따로 적용하지 않겠습니다 따로 기회가 되면 올려보도록 할게요!ㅎㅎ)

 

Server -> ACG생성

ACG이름 적용 Network Interface
issac-pub-pri wordpress-was
issac-pub-acg wordpress-web

(*만들다 보니... 이름을 잘못지었네요..ㅠㅠ issac-pub-pri는 private Subnet의 was에 적용되는 ACG입니다)

 

룰은 다음과 같이 만들어 줍니다.

issac-pub-acg inbound
issac-pub-acg outbound
issac-pub-pri inbound
issac-pub-pri outbound

 

마지막으로 아래의 룰을 두개의 ACG의 outbound에 추가합니다. 

(추가하지 않으면 epel 로 설치하는 Package가 설치 되지 않는다.)

공통 outbound 룰

 

아래 ACG설정은 CDB for MySQL을 생성후 진행한다,(아래 CDB for MySQL 생성하는 스텝 진행 후 올라와서 진행합니다)

CDB for MySQL inbound

 

ACG 설정하시느라 고생하셨어요! 이제 사전작업은 끝났습니다!

 

이제 서버와 DB를 생성하러 가보시죠!

+ Recent posts