쿠버네티스 전문가 양성과정 11주차 5일(3/3)

최수환·2023년 3월 3일
0

Kubernetes

목록 보기
50/75
post-thumbnail

각 언어의 빌드과정(워크플로우)

  • 각 프로그래밍 언어마다 빌드하는 과정이 다르고 특성도 다르다.

  • 이러한 각 언어의 빌드와 특성을 이해해야지만 개발자가 만든 코드가 git에 올라오면 코드를 빌드하고 Docker image로 만들고 쿠버네티스에 올리는(=배포) 작업을 할 수 있는 것이다.

  • git에 올라온 코드에 대해서 빌드하고 image로 만들고 K8S에 올리는 배포과정 까지를 Automation하는 것을 CI/CD or pipelineing이라고 한다.

  • AWS에서 ubuntu이미지 20.04버전, t3.medium , 스토리지 40G, 인터넷에서 HTTP트래픽 허용 클릭한 보안그룹 생성, 키페어 생성 한 인스턴스 생성

ssh -i mykey.pem ubuntu@54.180.97.180 
  • 생성한 인스턴스의 PUBLIC IP와 생성한 키페어를 통해 쉘에서 접속
git clone https://github.com/c1t1d0s7/example-hello.git
  • clone으로 github repo 다운로드
sudo hostnamectl set-hostname mybuild
exec bash
#보기편하게 hostname 변경

C언어

sudo apt update
sudo apt install gcc -y
# gcc다운로드, ubuntu이기 때문에 apt로 설치 


gcc hello.c -o hello # hello.c에 대해 hello실행파일 생성
  • -o : output옵션
  • hello라는 실행파일이 생성된다
file hello.c

  • 소스코드 파일인 것을 확인
file hello

  • ELF : 실행파일인 것을 확인
./hello # 실행파일 hello의 내용이 출력 

도커 설치

도커 설치 참조

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

sudo mkdir -m 0755 -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.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 docker-buildx-plugin docker-compose-plugin

sudo usermod -aG docker $USER # 일일이 sudo 안쓰고 관리자 권한으로 실행
  • 관리자 권한으로만 docker 실행 가능하기 때문이다.

docker image 생성

docker image pull ubuntu:focal

vi Dockerfile 

FROM ubuntu:focal # 이미지 다운 
COPY hello /usr/local/bin/ # hello실행파일을 디렉터리에 복사
CMD ["/usr/local/bin/hello"] # 해당 디렉터리에서 복사된 hello실행파일 실행 

docker image build -t hello-c .
  • hello world 한문장 실행시키는데 용량이 매우크다.
  • image가 매우 용량이 크기 때문이다.
  • 그렇다고 from없이 실행되지는 않는다.

scratch : 비어있는 이미지

vi Dockerfile

FROM scratch # 비어있는 이미지 사용 
COPY hello /usr/local/bin/
CMD ["/usr/local/bin/hello"]

docker image build -t hello-c:scratch . 
docker container run hello-c:scratch
  • scratch를 사용했기 때문에 용량이 매우적다
  • 하지만 실제로 run이 되지 않는다.
    -> 실행파일을 실행시킬 라이브러리가 존재하지 않는다
  • 예를들어 웹과 메신저가 있다고 가정하자. 각각은 TCP/IP통신을 해야한다. 각각 TCP/IP통신을 하기위한 라이브러리를 독자적으로 가지고 있는 것이 Static link 이다. 하지만 각각 라이브러리를 가지고 있다면 용량이 계속해서 늘어날 것이고 매우 비효율적이다.
  • 따라서 이 경우에는 dynamic link 를 통해 TCP/IP 라이브러리를 외부에 놓고 메신저와 웹이 해당 라이브러리를 참조만 하는 형태로 구성한다.
  • 하지만 Docker image생성에서는 현재 Static link를 사용하는 추세이다. 이유는, 필요한 라이브러리만 사용할 수 있기 때문에 오히려 이미지 측면에서는 용량을 줄일 수 있다.

📒 하지만 아직까지 대부분은 Dynamic link를 한다.

gcc hello.c -o hello # dynamic link

gcc hello.c -o hello-static --static # static link
  • static binary 생성
  • statically linked 시킨다
  • 독자적으로 라이브러리를 가지고 있다.
  • file 명령어를 통해 파일이 dynamic link인지, static link인지를 알 수 있다.
vi Docekrfile

FROM scratch # scratch 이미지 사용 
COPY hello-static /hello-static # static 실행파일 사용 
CMD ["/hello-static"] # static 실행파일 실행 

docker image build -t hello-c:static . # 이미지 생성
docker container run hello-c:static # run 
  • 정상적으로 run되서 helloworld 출력
#Build a binary with dynamically linked
FROM gcc:12 AS cbuilder
COPY . /usr/src/hello/
WORKDIR /usr/src/hello
RUN gcc hello.c -o hello

FROM ubuntu:focal
COPY --from=cbuilder /usr/src/hello/hello /hello
CMD ["/hello"]
  • multi-build 형태

golang

wget https://go.dev/dl/go1.18.10.linux-amd64.tar.gz
tar xf go1.18.10.linux-amd64.tar.gz
sudo cp -r go /usr/local
echo "export PATH=$PATH:/usr/local/go/bin" >> ~/.bashrc
source ~/.bashrc
  • go를 실행시키기 위한 컴파일러 설치
go run hello.go # go파일 실행
go build -o hello . # go파일 실행파일로 빌드
./hello # 실행파일 실행 

vi Dockerfile 

FROM scratch
COPY hello /hello
CMD ["/hello"]

docker image build -t hello-go:scratch .
docker container run hello-go:scratch 
  • 실행파일을 이미지로 만든다
FROM golang:1.18 AS gobuilder
ENV CGO_ENABLED=0
COPY . /usr/src/hello/
WORKDIR /usr/src/hello
RUN go build -o hello-http .

FROM scratch
COPY --from=gobuilder /usr/src/hello/hello-http /hello-http
CMD ["/hello-http"]
EXPOSE 3000/tcp
  • multi-build 형태

📌 빌드 순서

  • 개발자가 개발을 하고 나온 코드를 add와 commit 그리고 push를 통해 remote repo에 올린다.
  • 그 코드를 pull을 통해 갖고와서 언어에 맞게 run시켜보고 build를 통해 실행파일 형태로 생성한다.
  • dockerfile을 열어 생성한 실행파일을 이용해 multi-build형태로 작성하던, static link / dynamic link를 사용하든 작성하고 , dockerfile을 build해서 이미지를 생성한다.
  • 해당 이미지를 run시켜서 실행이 잘되는지 테스트하고 최종적으로 docker-hub와 같은 repository에 올린다
  • k8s를 이용해 올라온 이미지를 이용해 배포하면 된다.

nodejs

  • nodejs는 엄밀히 말하면 언어는 아니다
  • javascript와 java는 아예 아무런 관계가 없다
  • frontend(web browser) = js, html, css, 그림
  • nodejs는 js를 backend(서버)에서 사용하기 위해 개발
  • 비동기 처리 이벤트에 특화 되어있다.
sudo apt install npm -y # nodejs실행시키는 컴파일러 설치
npm insatll # node_modules 생성 

sudo apt install tree -y  
tree # node_modules가 가진 디렉터리 계층 보기 

npm start # .js파일을 실행시킨다

docker image 생성

docker image pull node:16 # 이미지 다운 

vi Dockerfile

FROM node:16 
COPY . /usr/src/hello/
WORKDIR /usr/src/hello
RUN npm install
CMD ["npm", "start"]
EXPOSE 8080/tcp

docker image build -t hello-node . # 이미지 빌드 
docker container run -d -p 8080:8080 hello-node

python

flask

python에서 가상환경은 중요하다.

sudo apt install python3-pip

python3 -m pip install --user -U virtualenv 
echo 'export PATH=$PATH:~/.local/bin' >> ~/.bashrc
source ~/.bashrc
virtualenv venv # 가상환경 이름 
# 기존의 패키지와 분리된 별도의 가상환경을 생성
# 패키지가 격리된 환경에서 사용된다

source venv/bin/activate
# venv가상환경에 접속     
pip install -r requirements.txt
# 시스템 전체에 설치하는 것이 아니라 가상환경에만 설치 

deactivate
# 가상환경 나가기 

export FLASK_APP=hello
flask run --host=0.0.0.0 --port=5000
# flask app실행 

< 이미지 생성 및 실행 >

vi Dockerfile

FROM python:3.8
ENV FLASK_APP=hello
COPY . /usr/src/hello/
WORKDIR /usr/src/hello
RUN pip3 install -r requirements.txt
CMD ["flask", "run", "--host=0.0.0.0", "--port=5000"] 
EXPOSE 5000/tcp

docker build -t hello-flask:v1 . # 이미지 생성 
docker container run -d -p 5000:5000 hello-flask:v1
# detach모드, 포트포워딩해서 run 

django

# 가상환경 deactivate한 후 
virtualenv venv # 현재 디렉터리에 새로운 가상환경 생성
source venv/bin/activate # 가상환경 접속
pip install -r requirements.txt # 패키지 설치 

python hello/manage.py runserver 0.0.0.0:8000
# django app 실행 

< 이미지 생성 및 실행 >

vi Dockerfile 

FROM python:3.8
COPY . /usr/src/hello/
WORKDIR /usr/src/hello
RUN pip3 install -r requirements.txt
CMD ["python3", "hello/manage.py", "runserver", "0.0.0.0:8000"]
EXPOSE 8000/tcp


docker build -t hello:v1 . # 이미지 생성 
docker container run -d -p 8000:8000 hello:v1
# detach모드, 포트포워딩해서 run

java

  • 기업에서 개발자가 가장 많이 사용하는 언어가 java이고 대부분은 java로 개발되어 있다. 따라서 기업에 가면 가장 많이 접하는 언어가 java이며 그만큼 제일 중요한 언어이다.
  • maven : 패키지 관리자
  • 패키지 생성
  • jar : java archive
  • war : web archive

< build lifecycle >

sudo apt install maven

lifecycle에서 중요한 4가지

clean
compile
test
package = complie + test


1 . jar파일

mvn package # target 생성 
java -jar target/spring-hello-0.0.1.jar
# java파일 실행시키는 법 	

vi Dockerfile # 이미지 생성하기 

FROM maven:3-openjdk-8 AS mbuilder
COPY . /usr/src/hello/
WORKDIR /usr/src/hello
RUN mvn package

FROM openjdk:8-jre
COPY --from=mbuilder /usr/src/hello/target/spring-hello-0.0.1.jar /usr/src/
CMD ["java", "-jar", "/usr/src/spring-hello-0.0.1.jar"]
# dockerfile 생성 

docker image build -t hello-java . # 이미지 생성
docker container run hello-java # run 

mvn clean # 새로운 빌드를 하기위해 기존의 package삭제 

2 . war파일

war파일은 java기반의 web-application서버가 필요하다

  • tomcat, 웹 로직, 와일드 스피어 등..
  • 주로 tomcat을 사용
mvn package # target 생성 
sudo apt install tomcat9 -y   
  • AWS의 보안그룹에서 8080포트 추가 후 브라우저에 EC2인스턴스의 PUBLIC IP:8080입력하면 tomcat webserver에 접속되는 것을 확인
sudo cp hello-world.war /var/lib/tomcat9/webapps/
  • tomcat의 root디렉터리인 /var/lib/tomcat9/webapps에 war파일을 복사하면 디렉터리에 있는 ROOT가 war파일을 알아서 푼다.

    -> 위에서 입력한 publicip:8080에 hello-world경로를 입력하면 웹페이지가 뜨는 것을 확인
    -> root디렉터리에 ROOT가 war파일을 풀었기 때문에 hello-world가 존재하게 된다. 따라서 웹페이지가 뜨는 것이다.
vi Dockerfile # 이미지 생성 

FROM maven:3-openjdk-8 AS mbuilder
COPY . /usr/src/hello/
WORKDIR /usr/src/hello
RUN mvn package

FROM tomcat:8-jre8
COPY --from=mbuilder /usr/src/hello/webapp/target/webapp.war /usr/local/tomcat/webapps/ROOT.war
EXPOSE 8080/tcp

docker image build -t hello:war .
docker container run -d -p 8080:8080 hello:war
# image 생성 및 run 
  • 이미지를 빌드할때는 port충돌이 발생할 수 있기 때문에 실행중인 컨테이너 종료와 tomcat9은 stop해줘야 한다
profile
성실하게 열심히!

0개의 댓글