티스토리 뷰
18 CI/CD Pipeline - Set Up a CI/CD Pipeline with Kubernetes Part 1: Overview
zerobig-k8s 2018. 9. 10. 06:46<출처>
이번 튜토리얼 시리즈에서, 배포 관리를 위한 간단한 CI/CD 파이프라인 함께 K8S에서 완전히 컨테이너화한 애플리케이션 스택을 설치하는 것이 얼마나 간단한 것인가를 보여준다.
소프트웨어 산업은 용이한 개발, 배포 그리고 앱 개발자를 위한 환경 오케스트레이션 방법으로 컨테이너를 이용하는 것에 대한 가치를 급속도로 깨달아 가고 있다. 그 이유는 컨테이너가 향상된 확장성을 고려하며, 환경적인 차이를 효과적으로 관리해주고, Continuous Delivery (CD) 기능을 지원해예측가능성을 제공해주기 때문이다.기술적인 이점들과 더불어, 고비용의 복잡한 환경 모델에 대한 극적인 절감효과를 보여주어 왔다.
컨테이너 내 탑재된 대 규모, 고 탄력(highly-elastic) 애플리케이션은 명백하게 혜택을 준다. 그러나 그 환경을 관리한다는 것은 벅찬 일이 될 것이다. 이러한 점에서 K8S와 같은 오케스트레이션 도구가 실로 그 빛을 발하게 해준다.
K8S는 구글에 의해 만들어진 플랫폼-불가지론(不可知論)의 컨테이너 오케스트레이션 툴이다. 그리고 CNCF(Cloud Native Computing Foundation)의 하나의 프로젝트로서 오픈 소스 커뮤니티에 의해 대대적인 지원을 받고 있다. 여러 개의 컨테이너 인스턴스를 구동 시키고 스케일링과 장애허용시스템(fault tolerance)을 통해 그것들을 관리해 준다. 또한 라우팅 요청, 컨테이너 디스커버리, 헬스체크, 그리고 롤링 업데이트를 포함한, 그 밖에 솔루션 분리 또는 사용자 정의 코드를 요청하게 되는, 광범위한 관리 업무들을 처리해 준다.
Kenzan은 대규모 애플리케이션을 제작하는데 있어 특화된 서비스 회사이다. Netflix OSS 스텍에 맞춰 마이크로서비스 기반 애플리케이션을 디자인하고 최근 컨테이너 테크놀러지의 유연성을 이용하여 프로젝트를 수행하면서 지난 10년 동안 클라우드 기술 진화를 지켜봐 왔다. 각 수행결과가 독자적이긴하나, 마이크로서비스와 CI/CD 의 결합이 매우 강력하다는 것을 발견하게 되었다.
Crossword Puzzles, Kubernetes, and CI/CD
이 기사는 4개의 블로그 게시물 시리즈 중 첫 번째 글이다. 우리의 목표는 배포 관리를 위한 간단한 CI/CD 파이프라인 함께 K8S에서 완전히 컨테이너화한 애플리케이션 스택을 설치하는 것이 얼마나 간단한 것인가를 보여주는 것이다.
시리즈의 모든 글을 읽어보자 .
Set Up a CI/CD Pipeline with Kubernetes Part 1: Overview
Set Up a CI/CD Pipeline with a Jenkins Pod in Kubernetes (Part 2)
Run and Scale a Distributed Crossword Puzzle App with CI/CD on Kubernetes (Part 3)
Set Up CI/CD for a Distributed Crossword Puzzle App on Kubernetes (Part 4)
이 시리즈를 위해 특별하게 창안한 애플리케이션에 대한 설치와 배포에 대해 설명하겠다. 일명 "Kr8sswordz Puzzle" 로, 몇몇의 주요 K8S 와 CI/CD 개념들을 함께 엮어볼 수 있도록 도와줄 것이다. 애플리케이션은 처음에 아주 간단하게 시작해서 진행해 나갈수록 완전한 애플리케이션 스택을 보여주는 컴포넌트들을 소개할 것이다. 더불어 그 스택을 관리하도록 돕는 CI/CD 파이프라인, 이 모든 것들이 K8S 위에서 컨테이너로써 동작하는 것을 보여 줄 것이다. 우리가 무엇을 만들려고 하는지 아래 아키텍쳐 다이어그램을 살펴보자.
완성된 애플리케이션은 빌드, 배포, 그리고 부하 상황에서 많은 인스턴스들을 구동 할 수 있도록 해주는 샌드박스를 생성함으로서, K8S가 앱과 인프라 둘 모두를 관리하는 것이 얼마나 막강하고 용이한 것인지에 대해 보여 줄 것이다.
Get Kubernetes up and Running
Kr8sswordz 퍼즐 애플리케이션을 만들기 위한 첫 단계는 K8S 를 설치하고 하나의 파드안에서 용이하게 컨테이너가 동작하도록 하는 것이다. 앞으로 설명하는 과정에서 필요한 몇 가지 도구들을 설치하게 될 것인데, Docker, Minikube, 그리고 Kubectl이 그것이다.
실습을 완성시키기 위해, Linux 또는 macOS의 최신버전이 설치되어 동작하고 있는 컴퓨터가 필요하고, 그 컴퓨터는 16GB의 메모리를 보유해야만 한다.
(하기 자동 스크립트 실행 과정을 지켜보면, 2CPUs, 8GB의 옵션을 할당하여 Minikube 를 구동함)
Exercise 1: Install Docker
Docker는 가장 범용적인 컨테이너 기술 중 하나로 K8S와 함께 직접적으로 동작한다. 이 실습 과정에서 Docker를 설치하고 몇 가지 명령을 수행해 볼 것이다.
Install Docker on Linux
Ubuntu 16.04 또는 그 이상의 버전에서 신속하게 Docker를 설치하기 위해서, 터미널 창을 하나 열어 다음 명령을 입력한다.(다른 배포판의 경우 Linux installation instructions 을 참고한다.)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | root@zerobig-vm-u:~# sudo apt-get update 기존:1 http://kr.archive.ubuntu.com/ubuntu xenial InRelease 기존:2 http://kr.archive.ubuntu.com/ubuntu xenial-updates InRelease 기존:3 http://kr.archive.ubuntu.com/ubuntu xenial-backports InRelease 기존:4 https://download.docker.com/linux/ubuntu xenial InRelease 기존:5 http://security.ubuntu.com/ubuntu xenial-security InRelease 패키지 목록을 읽는 중입니다... 완료 root@zerobig-vm-u:~# curl -fsSL https://get.docker.com/ | sh # Executing docker install script, commit: 36b78b2 Warning: the "docker" command appears to already exist on this system. If you already have Docker installed, this script can cause trouble, which is why we're displaying this warning and provide the opportunity to cancel the installation. If you installed the current Docker package using this script and are using it again to update Docker, you can safely ignore this message. You may press Ctrl+C now to abort this script. + sleep 20 + sh -c apt-get update -qq >/dev/null + sh -c apt-get install -y -qq apt-transport-https ca-certificates curl >/dev/null + sh -c curl -fsSL "https://download.docker.com/linux/ubuntu/gpg" | apt-key add -qq - >/dev/null + sh -c echo "deb [arch=amd64] https://download.docker.com/linux/ubuntu xenial edge" > /etc/apt/sources.list.d/docker.list + [ ubuntu = debian ] + sh -c apt-get update -qq >/dev/null + sh -c apt-get install -y -qq --no-install-recommends docker-ce >/dev/null + sh -c docker version Client: Version: 18.06.1-ce API version: 1.38 Go version: go1.10.3 Git commit: e68fc7a Built: Tue Aug 21 17:24:56 2018 OS/Arch: linux/amd64 Experimental: false Server: Engine: Version: 18.06.1-ce API version: 1.38 (minimum version 1.12) Go version: go1.10.3 Git commit: e68fc7a Built: Tue Aug 21 17:23:21 2018 OS/Arch: linux/amd64 Experimental: false If you would like to use Docker as a non-root user, you should now consider adding your user to the "docker" group with something like: sudo usermod -aG docker your-user Remember that you will have to log out and back in for this to take effect! WARNING: Adding a user to the "docker" group will grant the ability to run containers which can be used to obtain root privileges on the docker host. Refer to https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface for more information. | cs |
설치 후, Docker 그룹을 생성하여 root 아닌 사용자도 Docker 명령을 수행할 수 있도록 해준다.
1 | root@zerobig-vm-u:~# sudo usermod -aG docker $USER | cs |
모두 마쳤다면, Docker가 잘 돌고 있는지 확인해 보자.
1 2 3 | root@zerobig-vm-u:~# sudo service docker start root@zerobig-vm-u:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES | cs |
Install Docker on macOS
Docker for Mac (stable)을 다운로드하여 다음 설치 안내를 따른다. Docker를 구동하기 위해, 애플리케이션 폴더 내 Docker 아이콘을 더블 클릭한다. 구동이 되었다면, 메뉴 바에서 고래 아이콘이 보일 것이다.
Try Some Docker Commands
터미널 창을 열어 다음 명령을 입력하여 Docker 명령을 시험삼아 수행해 볼 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # Display the Docker version docker version # Pull and run the Hello-World image from Docker Hub docker run hello-world # Pull and run the Busybox image from Docker Hub docker run busybox echo "hello, you've run busybox" # View a list of containers that have run docker ps -a | cs |
Images는 컨테이너 구동에 필요한 모든 파일과 리소스를 정의한 스펙임을 주의한다. 많은 OSS 이미지들은 DockerHub에서 공개적으로 이용가능하다. Docker에 대해 추가 정보가 필요하면, Docker Getting Started를 참고한다. 명령어에 대한 전체 리스트는 The Docker Commands를 참고한다.
Exercise 2: Install Minikube and Kubectl
Minikube는 단일 노드 K8S 클러스터로 여러분의 컴퓨터 상에서 로컬로 K8S를 구동하기 쉽도록 해준다. 우리는 애플리케이션을 구동 할 메인 K8S 클러스터로 Minikube를 이용할 것이다.
이 실습에서 우리는 신속하게 Minikube와 kubectl을 설치해 볼 것이다.(더 자세한 내용은, Running Kubernetes Locally via Minikube을 확인해 본다.)
Install Virtual Box
latest version of VirtualBox에서 OS에 맞는 최신 버전을 다운 받는다. VirtualBox는 Minikube가 VM 기반의 K8S에서 동작하도록 해준다.
(Minikube 설치 on Ubuntu16.04 를 참고하여 진행한다.)
Install Minikube
OS에 맞게 권고되는 방식으로 Minikube releases page에서 Minikube 최신버전을 설치한다. Minikube는 K8S 노드에 설치될 것이다.
Linux의 경우, 다음 명령을 이용하여 Minikube를 설치한다. (9월 6일 현재 최신 버전은 v0.28.2 이다.)
1 2 3 4 | root@zerobig-vm-u:~# curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.28.2/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/ % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 38.5M 100 38.5M 0 0 1631k 0 0:00:24 0:00:24 --:--:-- 1619k | cs |
macOS의 경우, 다음 명령을 이용하여 Minikube를 설치한다. (9월 6일 현재 최신 버전은 v0.28.2 이다.)
Install Kubectl
퍼즐의 마지막 조각은 K8S 노드와 소통하기 위한 kubectl을 설치하는 것이다.
Linux의 경우, 다음 명령을 이용하여 kubectl을 설치한다.
1 2 3 4 5 6 7 | root@zerobig-vm-u:~# curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && chmod +x kubectl && sudo mv kubectl /usr/local/bin/ % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 52.8M 100 52.8M 0 0 1512k 0 0:00:35 0:00:35 --:--:-- 1838k root@zerobig-vm-u:~# kubectl version Client Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.2", GitCommit:"bb9ffb1654d4a729bb4cec18ff088eacc153c239", GitTreeState:"clean", BuildDate:"2018-08-07T23:17:28Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/amd64"} The connection to the server localhost:8080 was refused - did you specify the right host or port? | cs |
macOS의 경우, 다음 명령을 이용하여 kubectl을 설치한다.
Exercise 3: Install Prerequisites
다음 실습에서, 우리는 로컬 K8S 클러스터 를 구동하기 위해 Minikube를 이용하여 파드 몇 개를 배포하게 된다. 독자들은 실습과정에서 각각의 명령을 수동으로 입력해 볼 수 있지만, 단계를 밟아 나가는 과정에서 미리 만들어 둔 강좌용 스크립트를 이용하면 보다 쉽게 해결이 된다. 자, 대화형 튜토리얼을 시작해 보자.
Install NodeJS
강좌를 위해, NodeJS 와 npm을 설치해야 한다. (모든 명령을 수동으로 입력해 보고 싶다면 이 과정을 생략 할 수 있다.--솔직히 누가 그 많은 타이핑을 치려고 하겠는가?)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | root@zerobig-vm-u:~# curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash - ================================================================================ ================================================================================ DEPRECATION WARNING Node.js 7.x is no longer actively supported! You will not receive security or critical stability updates for this version. You should migrate to a supported version of Node.js as soon as possible. Use the installation script that corresponds to the version of Node.js you wish to install. e.g. * https://deb.nodesource.com/setup_8.x — Node.js 8 LTS "Carbon" (recommended) * https://deb.nodesource.com/setup_10.x — Node.js 10 Current Please see https://github.com/nodejs/Release for details about which version may be appropriate for you. The NodeSource Node.js distributions repository contains information both about supported versions of Node.js and supported Linux distributions. To learn more about usage, see the repository: https://github.com/nodesource/distributions ================================================================================ ================================================================================ Continuing in 20 seconds ... ## Installing the NodeSource Node.js 7.x repo... ## Populating apt-get cache... + apt-get update 기존:1 https://download.docker.com/linux/ubuntu xenial InRelease 기존:2 http://download.virtualbox.org/virtualbox/debian xenial InRelease 받기:3 http://security.ubuntu.com/ubuntu xenial-security InRelease [107 kB] 기존:4 http://kr.archive.ubuntu.com/ubuntu xenial InRelease 기존:5 http://kr.archive.ubuntu.com/ubuntu xenial-updates InRelease 기존:6 http://kr.archive.ubuntu.com/ubuntu xenial-backports InRelease 내려받기 107 k바이트, 소요시간 1초 (81.3 k바이트/초) 패키지 목록을 읽는 중입니다... 완료 ## Confirming "xenial" is supported... + curl -sLf -o /dev/null 'https://deb.nodesource.com/node_7.x/dists/xenial/Release' ## Adding the NodeSource signing key to your keyring... + curl -s https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - OK ## Creating apt sources list file for the NodeSource Node.js 7.x repo... + echo 'deb https://deb.nodesource.com/node_7.x xenial main' > /etc/apt/sources.list.d/nodesource.list + echo 'deb-src https://deb.nodesource.com/node_7.x xenial main' >> /etc/apt/sources.list.d/nodesource.list ## Running `apt-get update` for you... + apt-get update 기존:1 http://kr.archive.ubuntu.com/ubuntu xenial InRelease 기존:2 http://kr.archive.ubuntu.com/ubuntu xenial-updates InRelease 받기:3 https://deb.nodesource.com/node_7.x xenial InRelease [4,634 B] 기존:4 http://kr.archive.ubuntu.com/ubuntu xenial-backports InRelease 받기:5 https://deb.nodesource.com/node_7.x xenial/main Sources [758 B] 받기:6 https://deb.nodesource.com/node_7.x xenial/main amd64 Packages [969 B] 받기:7 https://deb.nodesource.com/node_7.x xenial/main i386 Packages [975 B] 기존:8 http://download.virtualbox.org/virtualbox/debian xenial InRelease 받기:9 http://security.ubuntu.com/ubuntu xenial-security InRelease [107 kB] 기존:10 https://download.docker.com/linux/ubuntu xenial InRelease 내려받기 114 k바이트, 소요시간 6초 (18.1 k바이트/초) 패키지 목록을 읽는 중입니다... 완료 ## Run `sudo apt-get install -y nodejs` to install Node.js 7.x and npm ## You may also need development tools to build native addons: sudo apt-get install gcc g++ make ## To install the Yarn package manager, run: curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list sudo apt-get update && sudo apt-get install yarn root@zerobig-vm-u:~# sudo apt-get install -y nodejs 패키지 목록을 읽는 중입니다... 완료 의존성 트리를 만드는 중입니다 상태 정보를 읽는 중입니다... 완료 다음 새 패키지를 설치할 것입니다: nodejs 0개 업그레이드, 1개 새로 설치, 0개 제거 및 0개 업그레이드 안 함. 11.3 M바이트 아카이브를 받아야 합니다. 이 작업 후 55.0 M바이트의 디스크 공간을 더 사용하게 됩니다. 받기:1 https://deb.nodesource.com/node_7.x xenial/main amd64 nodejs amd64 7.10.1-2nodesource1~xenial1 [11.3 MB] 내려받기 11.3 M바이트, 소요시간 0초 (12.8 M바이트/초) Selecting previously unselected package nodejs. (데이터베이스 읽는중 ...현재 218462개의 파일과 디렉터리가 설치되어 있습니다.) Preparing to unpack .../nodejs_7.10.1-2nodesource1~xenial1_amd64.deb ... Unpacking nodejs (7.10.1-2nodesource1~xenial1) ... Processing triggers for man-db (2.7.5-1) ... nodejs (7.10.1-2nodesource1~xenial1) 설정하는 중입니다 ... | cs |
macOS의 경우, download the NodeJS installer를 다운로드 하고 NodeJS와 npm을 설치하기 위해 .pkg 파일을 더블 클릭한다.
Fork the Git Repo
이제 자신만의 버전으로 Github 상의 Kubernetes CI/CD 레파지토리의 복사본을 생성할 차례다.
1. Git 설치 되어 있지 않다면 설치부터 하자.
1 2 3 4 5 6 7 | root@zerobig-vm-u:~# sudo apt-get install git 패키지 목록을 읽는 중입니다... 완료 의존성 트리를 만드는 중입니다 상태 정보를 읽는 중입니다... 완료 git is already the newest version (1:2.7.4-0ubuntu1.4). git 패키지는 수동설치로 지정합니다. 0개 업그레이드, 0개 새로 설치, 0개 제거 및 0개 업그레이드 안 함. | cs |
2. Github 에서 Kenzan’s Kubernetes CI/CD repository 를 Fork 한다. 여기에는 모든 컨테이너들과 Kr8sswordz 퍼즐 애플리케이션 관련 자료들이 포함되어 있다. 나중에 코드를 일부 수정하게 될 것이므로 fork 해 두는 것이 필요할 것이다.
a. Github 계정이 없다면, 가입부터 한다.
b. Kubernetes CI/CD repository 화면 우측 상단에 Fork 버튼을 클릭하고 지시에 따른다.
c. 홈 디렉토리인지 확인하고, 새로 fork한 레파지토리를 다음 터미널 명령을 이용하여 복제한다. (참고로 필자는 /home/study/k8s 를 기준으로 실습을 할 것이므로 해당 디렉토리로 이동한다. 여러분은 각자의 상황에 맞게 이동하면 된다.)
1 2 3 4 5 6 7 8 9 | root@zerobig-vm-u:~# mkdir -p /home/study/k8s root@zerobig-vm-u:~# cd /home/study/k8s/ root@zerobig-vm-u:/home/study/k8s# git clone https://github.com/zer0big/kubernetes-ci-cd.git 'kubernetes-ci-cd'에 복제합니다... remote: Counting objects: 2946, done. remote: Total 2946 (delta 0), reused 0 (delta 0), pack-reused 2946 오브젝트를 받는 중: 100% (2946/2946), 1.66 MiB | 374.00 KiB/s, 완료. 델타를 알아내는 중: 100% (1687/1687), 완료. 연결을 확인하는 중입니다... 완료. | cs |
Clear out Minikube
Minikube 에서 이전에 명령 수행하면서 남아 있을지 모를 잔재들을 없애버리자. 다음 명령을 터미널에 입력한다.
1 2 3 | root@zerobig-vm-u:/home/study/k8s# minikube delete; sudo rm -rf ~/.minikube; sudo rm -rf ~/.kube Deleting local Kubernetes cluster... Errors occurred deleting machine: Error deleting host: minikube: Error loading host from store: Docker machine "minikube" does not exist. Use "docker-machine ls" to list machines. Use "docker-machine create" to add a new one. | cs |
(위 에러는 minikube 를 구동한 이력이 없기 때문에 발생한 것이다. 이전에 구동한 이력이 있으면, 다음과 같이 나타날 것이다.)
1 2 3 | root@zerobig-vm-u:/home/study/k8s# minikube delete; sudo rm -rf ~/.minikube; sudo rm -rf ~/.kube Deleting local Kubernetes cluster... Machine deleted. | cs |
다음, 레파지토리가 복제된 디렉토리로 이동하여 강좌 스크립트를 설치한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | root@zerobig-vm-u:/home/study/k8s# cd kubernetes-ci-cd/ root@zerobig-vm-u:/home/study/k8s/kubernetes-ci-cd# npm install kubernetes-ci-cd@1.0.0 /home/study/k8s/kubernetes-ci-cd ├── cmdify@0.0.4 ├── colors@1.3.2 ├─┬ fetch-retry@1.2.1 │ ├── es6-promise@4.2.4 │ └─┬ isomorphic-fetch@2.2.1 │ ├─┬ node-fetch@1.7.3 │ │ ├── encoding@0.1.12 │ │ └── is-stream@1.1.0 │ └── whatwg-fetch@2.0.4 ├─┬ inquirer@3.3.0 │ ├── ansi-escapes@3.1.0 │ ├─┬ chalk@2.4.1 │ │ ├─┬ ansi-styles@3.2.1 │ │ │ └─┬ color-convert@1.9.3 │ │ │ └── color-name@1.1.3 │ │ ├── escape-string-regexp@1.0.5 │ │ └─┬ supports-color@5.5.0 │ │ └── has-flag@3.0.0 │ ├─┬ cli-cursor@2.1.0 │ │ └─┬ restore-cursor@2.0.0 │ │ ├─┬ onetime@2.0.1 │ │ │ └── mimic-fn@1.2.0 │ │ └── signal-exit@3.0.2 │ ├── cli-width@2.2.0 │ ├─┬ external-editor@2.2.0 │ │ ├── chardet@0.4.2 │ │ ├─┬ iconv-lite@0.4.24 │ │ │ └── safer-buffer@2.1.2 │ │ └─┬ tmp@0.0.33 │ │ └── os-tmpdir@1.0.2 │ ├── figures@2.0.0 │ ├── lodash@4.17.10 │ ├── mute-stream@0.0.7 │ ├─┬ run-async@2.3.0 │ │ └── is-promise@2.1.0 │ ├── rx-lite@4.0.8 │ ├── rx-lite-aggregates@4.0.8 │ ├─┬ string-width@2.1.1 │ │ └── is-fullwidth-code-point@2.0.0 │ ├─┬ strip-ansi@4.0.0 │ │ └── ansi-regex@3.0.0 │ └── through@2.3.8 ├── rx@4.1.0 └─┬ yamljs@0.2.10 ├─┬ argparse@1.0.10 │ └── sprintf-js@1.0.3 └─┬ glob@7.1.3 ├── fs.realpath@1.0.0 ├─┬ inflight@1.0.6 │ └── wrappy@1.0.2 ├── inherits@2.0.3 ├─┬ minimatch@3.0.4 │ └─┬ brace-expansion@1.1.11 │ ├── balanced-match@1.0.0 │ └── concat-map@0.0.1 ├── once@1.4.0 └── path-is-absolute@1.0.1 | cs |
잠깐!! 진행하기 전에
원문에서 제공하는 Minikube를 가지고 그대로 구동하게 되면, K8S 버전이 낮아서(v1.6.0) 구동이 완료되지 않는다.
따라서 다음과 같이 kubernetes-ci-cd 이하에 part1.yml 파일 내 Minikube 구동 조건을 기존 "--kubernetes-version v1.6.0" 에서 "--kubernetes-version v1.10.0" 으로 변경해준다.
1 2 3 4 5 6 7 8 9 | parts: - name: Part 1 intro: In this part we will setup a local cluster with minikube, deploy a public image from dockerhub, customize that image, and then finally deploy it inside our local cluster. steps: - cap: Start up the Kubernetes cluster with Minikube, giving it some extra resources. com: minikube start --memory 8000 --cpus 2 --kubernetes-version v1.10.0 ... | cs |
스크립트를 시작한다.
1 2 3 4 5 6 7 | root@zerobig-vm-u:/home/study/k8s/kubernetes-ci-cd# npm run part1 > kubernetes-ci-cd@1.0.0 part1 /home/study/k8s/kubernetes-ci-cd > node start.js part1.yml ? Welcome to the Linux.com interactive Kubernetes tutorial by Kenzan. Press enter to begin Yes | cs |
Exercise 4: Run a Test Pod
이번 실습에서 우리는 Docker 허브 상의 퍼블릭 이미지를 가지고 하나의 파드를 동작시킴으로써 Minikube 를 시험해 볼 것이다.
독자들은 실제로 하기 명령을 칠 필요가 없다 - 각 단계마다 엔터를 누르면 스크립트가 독자들을 대신하여 엔터를 입력해 줄 것이다.
1. 추가의 리소스들을 할당하기 위해 Minikube 와 함께 K8S 클러스터를 구동한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | Part 1 Step: 1 Start up the Kubernetes cluster with Minikube, giving it some extra resources. minikube start --memory 8000 --cpus 2 --kubernetes-version v1.10.0 Press enter to run the above command for the step. Yes Starting local Kubernetes v1.10.0 cluster... Starting VM... Downloading Minikube ISO 160.27 MB / 160.27 MB [============================================] 100.00% 0s Getting VM IP address... Moving files into cluster... Downloading kubeadm v1.10.0 Downloading kubelet v1.10.0 Finished Downloading kubeadm v1.10.0 Finished Downloading kubelet v1.10.0 Setting up certs... Connecting to cluster... Setting up kubeconfig... Starting cluster components... Kubectl is now configured to use the cluster. Loading cached images from config file. | cs |
2. Minikube 의 Heapster 와 Ingress 애드 온을 사용가능하게 해준다.
1 2 3 4 5 6 7 8 | Part 1 Step: 2 Enable the Minikube add-ons Heapster and Ingress. minikube addons enable heapster; minikube addons enable ingress Press enter to run the above command for the step. Yes heapster was successfully enabled ingress was successfully enabled | cs |
또 다른 터미널 창에서, 파드와 클러스터에 대해 점검해 볼 수 있다. 독자들은 애드 온 heapster, influxdb-grafana, 그리고 nginx-ingress-controller 를 볼 수 있을 것이다. 다음 명령을 수행한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | root@zerobig-vm-u:/var/log# kubectl get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system default-http-backend-59868b7dd6-b9rqt 1/1 Running 0 5m kube-system etcd-minikube 1/1 Running 0 4m kube-system heapster-vpztx 1/1 Running 0 5m kube-system influxdb-grafana-84vm6 2/2 Running 0 5m kube-system kube-addon-manager-minikube 1/1 Running 0 5m kube-system kube-apiserver-minikube 1/1 Running 0 5m kube-system kube-controller-manager-minikube 1/1 Running 0 5m kube-system kube-dns-86f4d74b45-cqpr4 3/3 Running 0 5m kube-system kube-proxy-zscx5 1/1 Running 0 5m kube-system kube-scheduler-minikube 1/1 Running 0 5m kube-system kubernetes-dashboard-5498ccf677-dcbwc 1/1 Running 0 5m kube-system nginx-ingress-controller-5984b97644-n8lmr 1/1 Running 0 5m kube-system storage-provisioner 1/1 Running 0 5m | cs |
3. 20초 정도 기다린다. 그리고 나서 Minikube 대쉬보드에서 관리하고 있는 디플로이먼트 용 웹 UI를 볼 수 있다. 대쉬보드에서 바로 보이지 않는다면, 웹 브라우저를 새로고침 해야할 수도 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Part 1 Step: 3 Wait 20 seconds, and then view the Minikube Dashboard, a web UI for managing deployments. sleep 20; minikube service kubernetes-dashboard --namespace kube-system Press enter to run the above command for the step. Yes Opening kubernetes service kube-system/kubernetes-dashboard in default browser... /usr/bin/xdg-open: 778: /usr/bin/xdg-open: www-browser: not found /usr/bin/xdg-open: 778: /usr/bin/xdg-open: links2: not found /usr/bin/xdg-open: 778: /usr/bin/xdg-open: elinks: not found /usr/bin/xdg-open: 778: /usr/bin/xdg-open: links: not found /usr/bin/xdg-open: 778: /usr/bin/xdg-open: lynx: not found /usr/bin/xdg-open: 778: /usr/bin/xdg-open: w3m: not found xdg-open: no method available for opening 'http://192.168.99.100:30000' | cs |
(필자의 경우, 현재 쉘을 수행하는 위치가 HostOS(Windows) 상의 터미널이므로 위 에러가 발생했다. 혹시라도 필자와 같은 상황이라면, GuestOS에서 수동으로 다음과 같이 대쉬보드를 구동해 준다.)
root@zerobig-vm-u:~
# minikube service kubernetes-dashboard --namespace kube-system
Opening kubernetes service kube-system
/kubernetes-dashboard
in
default browser...
(잠시 후 대시보드가 구동되면 Namespace를 "All namespaces" 로 변경하여 확인해 보면 다음과 같은 화면이 출력된다.)
4. Docker 허브로 부터 파드내에 컨테이너 안으로 퍼블릭 Nginx 이미지를 배포한다. Nginx 이미지가 로컬에 존재하지 않을 경우, 자동으로 Docker 허브로 부터 다운로드 되어진다.
1 2 | root@zerobig-vm_u:~# kubectl run nginx --image nginx --port 80 deployment.apps/nginx created | cs |
명령이 수행된 후, Minikube 대쉬보드의 Heapster 그래프(그래프가 안보이면, 몇분 더 기다리자.) 에서 새로 배포된 것을 확인할 수 있을 것이다.
5. 디플로이머트를 위한 서비스를 생성하자. 이는 Nginx 파드를 웹 서버에서 접근할 수 있도록 노출시켜 줄 것이다.
1 2 3 4 5 6 7 | Part 1 Step: 5 Create a service for deployment. This will expose the nginx pod so you can access it with a web browser. kubectl expose deployment nginx --type NodePort --port 80 Press enter to run the above command for the step. Yes service/nginx exposed | cs |
6. 서비스를 테스트하기 위해 웹 서버를 구동한다. Nginx 웰컴 페이지가 보여진다면, 서비스가 올라와 잘 돌고 있음을 의미한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Part 1 Step: 6 Launch a web browser to test the service. The nginx welcome page displays, which means the service is up and running. minikube service nginx Press enter to run the above command for the step. Yes Opening kubernetes service default/nginx in default browser... /usr/bin/xdg-open: 778: /usr/bin/xdg-open: www-browser: not found /usr/bin/xdg-open: 778: /usr/bin/xdg-open: links2: not found /usr/bin/xdg-open: 778: /usr/bin/xdg-open: elinks: not found /usr/bin/xdg-open: 778: /usr/bin/xdg-open: links: not found /usr/bin/xdg-open: 778: /usr/bin/xdg-open: lynx: not found /usr/bin/xdg-open: 778: /usr/bin/xdg-open: w3m: not found xdg-open: no method available for opening 'http://192.168.99.100:32367' | cs |
(필자의 경우, 현재 쉘을 수행하는 위치가 HostOS(Windows) 상의 터미널이므로 위 에러가 발생했다. 혹시라도 필자와 같은 상황이라면, GuestOS의 터미널에 다음 명령을 수행한다. 같은 상황이 반복되므로 이후 추가 커맨트는 생략할 예정이니 참고하기 바란다.)
1 2 | root@zerobig-vm-u:~# minikube service nginx Opening kubernetes service default/nginx in default browser... | cs |
(잠시 후 자동으로 브라우저가 열리면서 nginx 환영 메시지를 확인할 수 있다.)
Exercise 5: Create a Local Image Registry
이전 실습에서, 우리는 Docker 허브로부터 하나의 퍼블릭 이미지를 구동했다. Docker 허브가 퍼블릭 이미지에 대해서는 대단하긴 하나, 사이트에 프라이빗 이미지 레지스트리를 구성할 때 우리가 다루고 싶어하지 않는 보안 키 오버헤드에 엮이게 된다. 대신 우리는 우리들만의 로컬 이미지 레지스트리를 설치할 것이다. 우리는 빌드, 푸쉬 그리고 로컬 레지스트리의 샘플 Hello-Kanzen 앱을 동작시킬 것이다. (나중에, 우리는 우리의 Kr8sswordz 퍼즐 앱의 컨테이너 이미지들을 저장할 때 그 레지스트리를 사용할 것이다.)
인터렉티브 강좌는 여전히 돌고 있다. – 단지 각 단계별로 엔터만 누르면 된다.
7. yml manifest 파일을 적용하여 클러스터 레지스트리를 설치한다.
1 2 3 4 5 6 7 8 9 10 11 | Part 1 Step: 7 Set up the cluster registry by applying a .yml manifest file. kubectl apply -f manifests/registry.yml Press enter to run the above command for the step. Yes persistentvolume/registry created persistentvolumeclaim/registry-claim created service/registry created service/registry-ui created deployment.extensions/registry created | cs |
8. 레지스트리가 배포를 마칠때 까지 기다린다. 이는 몇분 소요됨을 참고하자.
(참고로 기다리는 동안, 추가의 창에서 진행 상태를 확인할 수 있다. )
1 2 3 4 | root@zerobig-vm-u:/var/log# kubectl get deployments | grep registry registry 1 1 1 1 2m root@zerobig-vm-u:/var/log# kubectl get pods | grep registry registry-95c457bdb-hcvsd 2/2 Running 0 2m | cs |
1 2 3 4 5 6 7 | Part 1 Step: 8 Wait for the registry to finish deploying. Note that this may take several minutes. kubectl rollout status deployments/registry Press enter to run the above command for the step. Yes deployment "registry" successfully rolled out | cs |
9. 웹 브라우저에서 레지스트리 UI를 보자. 당장은 빈 화면이지만 곧 변경된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Part 1 Step: 9 View the registry user interface in a web browser. minikube service registry-ui Press enter to run the above command for the step. Yes Opening kubernetes service default/registry-ui in default browser... /usr/bin/xdg-open: 778: /usr/bin/xdg-open: www-browser: not found /usr/bin/xdg-open: 778: /usr/bin/xdg-open: links2: not found /usr/bin/xdg-open: 778: /usr/bin/xdg-open: elinks: not found /usr/bin/xdg-open: 778: /usr/bin/xdg-open: links: not found /usr/bin/xdg-open: 778: /usr/bin/xdg-open: lynx: not found /usr/bin/xdg-open: 778: /usr/bin/xdg-open: w3m: not found xdg-open: no method available for opening 'http://192.168.99.100:30588' | cs |
(GuestOS 터미널 창에서 다음 명령을 수행하면 빈 레지스트리 UI를 확인할 수 있다.)
1 2 | root@zerobig-vm-u:~# minikube service registry-ui Opening kubernetes service default/registry-ui in default browser... | cs |
10 . 복제된 프로젝트에서 HTML 파일을 변경해 보자. 다음 명령을 수행하면 nano 텍스트 편집기에서 /applications/hello-kenzan/index.html 이 열릴 것이다.
<p> 태크들 중 하나 안에서 일부 텍스트를 변경한다. 예를들어, “Hello from Kenzan!” 을 “Hello from Me!” 로 변경한다. 변경이 완료되면, Ctrl+X 를 눌러 빠져 나온다. 저장을 위한 프롬프트가 뜨면 — 저장을 위해 Y 를 누르고 특정 파일에 기록을 위해 Enter 를 친다.
1 2 3 4 5 6 7 | Part 1 Step: 10 Let’s make a change to an HTML file in the cloned project. Open the /applications/hello-kenzan/index.html file in your favorite text editor (for example, you can use nano by running the command 'nano applications/hello-kenzan/index.ht ml' in a separate terminal). Change some text inside one of the <p> tags. For example, change “Hello from Kenzan!” to “Hello from Me!”. Save the file. echo '' Press enter to run the above command for the step. Yes | cs |
11. 이제 이미지를 빌드해 보자. 특정 이름을 할당하고 우리의 로컬 클러스터 레지스트리를 지정해 주자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | Part 1 Step: 11 Now let’s build an image, giving it a special name that points to our local cluster registry. docker build -t 127.0.0.1:30400/hello-kenzan:latest -f applications/hello-kenzan/Dockerfile applications/hello-kenzan Press enter to run the above command for the step. Yes Sending build context to Docker daemon 70.14kB Step 1/4 : FROM nginx:latest latest: Pulling from library/nginx 802b00ed6f79: Pull complete e9d0e0ea682b: Pull complete d8b7092b9221: Pull complete Digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3 Status: Downloaded newer image for nginx:latest ---> 06144b287844 Step 2/4 : COPY index.html /usr/share/nginx/html/index.html ---> 04fd4fa27118 Step 3/4 : COPY DockerFileEx.jpg /usr/share/nginx/html/DockerFileEx.jpg ---> 2d276f63f0e2 Step 4/4 : EXPOSE 80 ---> Running in facbdc4794df Removing intermediate container facbdc4794df ---> 486e8957396a Successfully built 486e8957396a Successfully tagged 127.0.0.1:30400/hello-kenzan:latest | cs |
12. 이미지를 빌드했다. 레지스트리에 푸쉬하기 전에, 임시 프록시를 구성해야 한다. 기본적으로 Docker 클라이언트는 로컬호스트를 통해 HTTP(HTTPs 가 아닌)로만 푸쉬할 수 있다. 임시방편으로, 127.0.0.1:30400 에서 서비스 리슨하도록 컨테이너를 구성하고 우리의 클러스터로 포워드하면 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Part 1 Step: 12 We’ve built the image, but before we can push it to the registry, we need to set up a temporary proxy. By default the Docker client can only push to HTTP (not HTTPS) via localhost. To work around this, we’ll set up a container that li stens on 127.0.0.1:30400 and forwards to our cluster. docker stop socat-registry; docker rm socat-registry; docker run -d -e "REGIP=`minikube ip`" --name socat-registry -p 30400:5000 chadmoon/socat:latest bash -c "socat TCP4-LISTEN:5000,fork,reuseaddr TCP4:`minikube ip`:30400" Press enter to run the above command for the step. Yes Error response from daemon: No such container: socat-registry Error: No such container: socat-registry Unable to find image 'chadmoon/socat:latest' locally latest: Pulling from chadmoon/socat 627beaf3eaaf: Pull complete f2bcbd47243c: Pull complete f4175031eafb: Pull complete 35070a1aa40d: Pull complete Digest: sha256:14bfffdd5fbcec8e30b263dc29fc2b48c73a09c5eed9a00dc0d5efb8e83eba94 Status: Downloaded newer image for chadmoon/socat:latest d5a2060b22183033d97cb7f0b966ecfef57be1eb925c1f8644e409e1466ffe76 | cs |
13. 프록시 컨테이너를 올려 동작시키두고, 로컬 레파지토리에 우리의 이미지를 푸쉬할 수 있다.
레지스트리, UI 와 함게 브라우저 창을 리프레쉬하면 이미지가 나타날 것이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 | Part 1 Step: 13 With our proxy container up and running, we can now push our image to the local repository. docker push 127.0.0.1:30400/hello-kenzan:latest Press enter to run the above command for the step. Yes The push refers to repository [127.0.0.1:30400/hello-kenzan] 0eef634145d8: Pushed a6e768b045ab: Pushed 579c75bb43c0: Pushed 67d3ae5dfa34: Pushed 8b15606a9e3e: Pushed latest: digest: sha256:1397d069919d809b6bbbb107d6bfe1fe188b5cf6a068d9e8e7558584c893b1fd size: 1364 | cs |
14. 프록시가 동작되었으니, 진행을 계속하거나 멈출 수 있다.
1 2 3 4 5 6 7 | Part 1 Step: 14 The proxy’s work is done, so you can go ahead and stop it. docker stop socat-registry; Press enter to run the above command for the step. Yes socat-registry | cs |
15. 클러스터 레지스트리에 이미지를 가지고, 수행해 볼 마지막 내용은 이 이미지를 토대로 hello-kenzan 를 생성하고 배포되도록 manifest를 적용하는 것이다.
1 2 3 4 5 6 7 8 | Part 1 Step: 15 With the image in our cluster registry, the last thing to do is apply the manifest to create and deploy the hello-kenzan pod based on the image. kubectl apply -f applications/hello-kenzan/k8s/deployment.yaml Press enter to run the above command for the step. Yes service/hello-kenzan created deployment.extensions/hello-kenzan created | cs |
16. 웹 브라우저를 구동하여 서비스 내용을 보자.
index.html 파일에 가한 변경을 주목하자. 변경사항은 여러분들이 빌드하고 레지스트리에 푸쉬할 때, 이미지에 반영되어 졌다. 아주 짱이다!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Part 1 Step: 16 Launch a web browser and view the service. minikube service hello-kenzan Press enter to run the above command for the step. Yes Opening kubernetes service default/hello-kenzan in default browser... /usr/bin/xdg-open: 778: /usr/bin/xdg-open: www-browser: not found /usr/bin/xdg-open: 778: /usr/bin/xdg-open: links2: not found /usr/bin/xdg-open: 778: /usr/bin/xdg-open: elinks: not found /usr/bin/xdg-open: 778: /usr/bin/xdg-open: links: not found /usr/bin/xdg-open: 778: /usr/bin/xdg-open: lynx: not found /usr/bin/xdg-open: 778: /usr/bin/xdg-open: w3m: not found xdg-open: no method available for opening 'http://192.168.99.100:31740' complete | cs |
1 2 | root@zerobig-vm-u:~# minikube service hello-kenzan Opening kubernetes service default/hello-kenzan in default browser... | cs |
이제 Minikube에서 작업을 마쳤다면, 다음 명령을 수행하여 계속 진행하거나 클러스터를 종료시킬 수 있다.
1 2 3 | root@zerobig-vm-u:/home/study/k8s/kubernetes-ci-cd# minikube stop Stopping local Kubernetes cluster... Machine stopped. | cs |
Up Next
여태가지, 우리는 Docker, Minikube, 그리고 Kubectl을 설치해봤고 Kr8sswordz 퍼즐 스텍을 빌드하기 위해, Minikube 내 파드 형태로 우리의 이미지 레파지토리를 동작시켜 봤다. 그리고 Hello-Kenzan 앱을 이용해 빌드하고 푸쉬하는 테스트를 할 수 있었다.
계속하여 시리즈의 파트 2 에서 Jenkins 자체를 파드로 동작하게 CI/CD 컴포넌트에 추가함으로써 인프라에 빌드해나가 볼 것이다. 젠킨스 2.0 파이프라인 스크립트를 이용하여, 나중에 Kr8sswordz 퍼즐 앱을 가지고 이용하게 될 지속적인 배포를 위한 인프라를 제공하여 Hello-Kenzan 앱을 빌드, 푸쉬 그리고 배포해 볼 것이다. K8S 내에 젠킨스 컨테이너로부터 컨테이너를 배포하는 것이 다소 혼란일 수도 있겠으나, Part 2 에서 이러한 방식의 배포를 다루는 것이 얼마나 쉬운 것인가를 보여줄 것이다.