선 리눅스 명령어 공부

 

pwd 나의 위치 볼 수 있다

cd .. 하면 그 상위 경로로 이동할 수 있다

cd $HOME   (그냥 cd home하면 home이란 이름의 디렉토리 찾기 때문에 예약된 $HOME이란 이름 사용)

mkdir 파일 만들기

dir 있는 파일들 보기

ls -al 숨겨지고 자세한 정보보기

touch 빈 텍스트 파일 만들기

cat 텍스트 파일 안에 내용 보기

 

FROM  퇴적층처럼 쌓아올린 docker file 에서 한층 더 쌓아서 docker를 만들 수도 있는데 그 이전까지는 base image라고 하는데 그런 base image를 어디부터 사용할지 지정

COPY 특정한 파일 혹은 디렉토리를 복사해서 넣어준다

 

RUN (도커 파일을 가지고 도커 이미지 만들 때 사용한다) 도커 컨테이너가 실제로 동작이 될 때 만약 ubuntu 환경이라면, 안에 환경 세팅도 되어있을 것이다(np, pd, sklearn). 안에 환경 세팅을 넣어주는 것도 방법이지만 RUN 뒤에 명령어로 저런 환경 세팅을 설치해주는 방법도 있다. 또는 text file안에 필요한 걸 다 써주고 그 파일을 실행하라고 명령할 수도 있다.

CMD (도커 이미지를 가지고 도커를 실행할 때) 컨테이너가 실행될 때 딱 하나의 명령만 실행할 수 있다. 주로 파이썬으로 짠 코드가 바로 실행되길 바란다할 때 사용(CMD python main.py)

 

WORKDIR 작업할 디렉토리 지정, 지정한 명령들이 그 안에서 작동, 생략하면 그냥 home디렉토리에서 실행

ENV 시스템 환경 변수 세팅, kay와  value로 이루어져 있다.

 

EXPOSE docker를 이용하여 작업할 때, 내가 사용하는 시스템 위에서 그 docker 컨테이너들이 동작할 텐데 바로 외부에 접속이 안된다. 왜냐하면 일단 docker 자체는 외부로 부터 보안상 격리당해있기 때문이다. 그래서 특정 docker는 외부로 통신을 위해 열어줘야하는 작업을 해야한다. 포트와 프로토콜 값이 필요한다 프로토콜 지정안해주면 기본적으로 TCP로 된다.

 

 

이번 과정에서는 도커를 직접 만들지만 관리는 어떻게 하는 게 좋을까?

예제로 티켓 링크 웹사이트를 만들고 컨테이너를 하나 만들었을 때, 유명한 가수 콘서트를 하면 사용자들이 폭주할텐데 그럼 도커 컨테이너 하나로는 부족하고 컨테이너를 많이 늘려야할 것이다. 그럼  컨테이너 갯수가 자동으로 늘었다가 사용자가 줄면 다시 자동으로 줄기를 원할 것이다. 이걸 하나하나 손수 하긴 힘들기 때문이다. 이 때 사용하게 되는데 쿠바네티스이다.

 


docker file만들기

cd $HOME

mkdir docker-practice

cd docker-practice/ 해당 파일로 들어오기 #cd docker 까지 치고 tab누르면 파일이름이 변별력이있어 나머지 자동입력해줌



#이제 여기 텍스트 파일을 하나 만들건데 Dockerfile이미 정해져있는 거니까 대소문자 잘지키기

touch Dockerfile  

ls # 위에 만든 Dockerfile 파일 생성된 거 알 수 있다.

cat Dockerfile # 안에 내용없음

 

 

docker image 만들기 준비

vi Dockerfile  # vi에디터로 열기

#i 눌러서 insert 모드로 변경

#도커 베이스 이미지 지정
FROM ubuntu:18.04

# Apt-get 업데이트 자동으로
RUN apt-get update        # Docker 안이라 sudo 하지 않아도 된다

#도커 실행될 때["명령어","명령어 파라메터"]
CMD ["echo","Hello Microsoft AI 2"]   # 명령어는 리눅스언어로 사용

#저장
ESC 키로 명령모드로 변경
:wq #저장하고 빠져나가기

#저장 잘 되었는지 확인
cat Dockerfile

 

docker image 만들기

# build 명령어로 같은 디렉토리내 파일 참조해서 'my-image:v0.0.0' 이란 이미지 만든다
# -t 는 태그(버전)를 달아준다는 뜻
# 끝에 .은 이미지를 이 위치에 만들겠다는 뜻

docker build -t my-image:v1.0.0 .

# 이제 설치가 됐을 것이다.
#도커파일이 있고 이미지는 어디 생겼는지 확인 
docker images

 

지금 사용중인 리눅스 가상 pc가 있고 여기엔 지금 docker를 설치하고 docker image를 생성한 상태.

도커 컨테이너를 만들어서 실행을 해보자.

#생성해둔 이미지로 컨테이너 만들기
docker run --name demo1 my-image:v1.0.0

docker image 활용 방법1

local pc에서 사용

 

docker image 활용 방법2

내 파일 시스템에만 있던 docker image를 다른 사람과 공유하여 사용하고 싶을 때

(1)서버(local docker rigistry의 역할)를 하나 만들어서 업로드한다. 필요할 때 서버에 요청해서 다운로드 받아 사용

(2) 클라우드 이용. docker hub 라는 사이트를 이용하여 이 곳에 docker image업로드 하여 사용

 

docker image 활용 방법3

클라우드 이용. Azure의 ACR 서비스 이용하여 도커 파일 바로 올려 사용가능

또 AKS(애저 쿠버네티스 서비스)도 있는 거 참고 

 

저장되는 공간은 repository 저장하는 시스템은 rigistry

 


 

docker image 활용 방법1

<Local repository 활용 : 우리가 만든 서버에 docker image 넣기>

# registry 이미지 만들기(registry도 이미지로 가져와야함)
# -d :daemon / -p: 외부에서 접근할 포트넘버(들어오는 포트 :나가는 포트 ) / 컨테이너 이름 registry로 짓기
docker run -d -p 5000:5000 --name registry registry

docker ps         # 이제 registry 라는 컨테이너 실행중인게 보인다


# 내가 만든 my-image와 registry 이미지가 있는지 확인
docker images 


#image 중에 내가 찾고싶은 이미지 쉽게 찾기
docker images | grep my-image



#이제 resistry에 도커 이미지를 넣어보자

# my-image:v1.0.0는 앞으로 localhost:5000의 my-image:v1.0.0라고 지정
docker tag my-image:v1.0.0 localhost:5000/my-image:v1.0.0


# 이미지 밀어넣기, local host:(포트넘버)에 접속하여 넣는다는 뜻
docker push localhost:5000/my-image:v1.0.0

#공장이나 군대에선 이렇게도 쓰는데 보통은 클라우드 사용


#push 잘되었는지 확인
curl -X GET http://localhost:5000/v2/_catalog

# 더 자세히 알아보자
curl -X GET http://localhost:5000/v2/my-image/tags/list

그러나 이 방법은 서버가 죽으면 다 죽어서 좋지 않은 방식이다.

 

 

 

docker image 활용 방법2

<docker hub 활용하고 쿠버네티스 사용해보기>

 

(1) docker hub 활용

https://hub.docker.com/

 

Docker Hub Container Image Library | App Containerization

Deliver your business through Docker Hub Package and publish apps and plugins as containers in Docker Hub for easy download and deployment by millions of Docker users worldwide.

hub.docker.com

이 사이트에 가입한 id가 내 주소가 된다.

이제 다시 프롬프트 명령으로 작업을 한다.

# 초반 설치할 때 'cli'는 command line interface의 약자로 명령어로 입력하는 모든 도구를 CLI라고 부른다

# docker hub 접속
docker login 
#내 docker hub id과 passward 입력해서 로그인

# docker hub, wlsl6569/my-image:v1.0.0에 로컬작업했던 my-image:v1.0.0를 연결
docker tag my-image:v1.0.0 wlsl6569/my-image:v1.0.0

#image push
docker push wlsl6569/my-image:v1.0.0

 

이제 docker hub 사이트의 repository에 가보면 생성되어있다.

이제 다른 사람들과 공유가능

더보기

또 이 과정 까지 계속 따라왔다면  docker images 쳤을 때 다른 repository에 존재하는 세가지 같은 파일이 존재함을 알 수 있다.

 

 

(2) 쿠버네티스 사용

더보기

Kubernetes?

 

많은 docker container(컨테이너화된 애플리케이션)을 배포, 스케일링, 관리하는 데 사용되는 오픈소스 플랫폼으로

2018년 부터 GA(일반 공개) 되었다.

원천 소스는 하나지만 배포판은 여러 개로 이번 과정에서는 minikube 라는 버전으로 테스트할 것이다. 

 

-보통 서버(or VM)가 3개는 있어야 세팅이 됐다.(minikube 이전) 얘네가 쿠버네티스 마스터에 서버마다 워크노드로 연결돼어 관리 받는데, 우리가 명령을 내릴 때도 쿠버네티스 마스터에 시킨다. 

-서버마다 컨테이너를 담는 단위는 pod라고 한다.

-kube-proxy는 외부와 통신하는 역할을 한다.

-쿠버네티스 전체도 컨테이너로 되어있다.

 

쿠버네티스 마스터는 CLI(command line interface)를 통해 부릴 수 있고 cli는 kubectl을 설치해서 쿠버네티스 하나에 워크 노드 하나로 사용할 것이다.

설치하기 : minikube, kubectl

 

 

https://minikube.sigs.k8s.io/docs/start/

https://kubernetes.io/ko/docs/tasks/tools/install-kubectl-linux/ 

 

리눅스에 kubectl 설치 및 설정

시작하기 전에 클러스터의 마이너(minor) 버전 차이 내에 있는 kubectl 버전을 사용해야 한다. 예를 들어, v1.27 클라이언트는 v1.26, v1.27, v1.28의 컨트롤 플레인과 연동될 수 있다. 호환되는 최신 버전

kubernetes.io

 

cmd에서 아래 명령어 입력해서 다운로드(curl -LO는 주소에 있는 것 다운로드)

# cmd에서 아래 명령어 입력해서 다운로드(curl -LO는 웹서버에 있는 것 다운로드)
curl -LO https://storage.googleapis.com/minikube/releases/v1.22.0/minikube-linux-amd64

#확인
ls

# 설치
sudo install minikube-linux-amd64 /usr/local/bin/minikube

#잘 설치됐나 확인
minikube version 
minikube --help   설치확인 완료

#이제 워크노드와 쿠베 마스터까지 연결설치 되어있다
# ctl 다운로드
curl -LO https://dl.k8s.io/release/v1.22.1/bin/linux/amd64/kubectl

# ctl 설치, 권한 위치도 같이 줘야함(전체 쿠버네티스를 
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
# -o root owner가 root라는 뜻 group도 root라는 뜻

# 설치됐는지 확인
kubectl version
kubectl --help

 

# minikube 실행
minikube start --driver=docker
# 실행되며 cpu2개와 4GB 메모리를 사용하는 걸 볼 수 있다. (최소 사양)

# 현재 상태 확인
minikube status
# pod에 대한 정보 보기(pod는 워크노드에서 컨테이너 담는 그릇)
kubectl get pod

# 이 system에 사용하고 있는 pod 보기 
kubectl get pod -n kube-system

# minikube 삭제하기
minikube delete (메모리에 있는 미니쿠베만 삭제하는 거고 미니쿠베 자체를 삭제하려면 minikube uninstall)

 


pod 생성

YAML 

 

더보기

YAML 포맷?

인간이 쉽게 읽을 수 있고 쓸 수 있는 데이터 직렬화 양식입니다. 주로 데이터 구조, 설정 파일 및 메시지 전송 프로토콜 등에서 사용,( YAML말고 JSON포맷도 많이 사용)

 

데이터의 직렬화?

예를 들어 어떤 Class를 만들었다하면, 그 안에 method와 property가 있고 여기 속성도 여러개 있을 것이다.

이 class를 A 시스템에서 잘 사용하다가 B 시스템으로 보낸다고 할 때 네트워크로 보내고 싶을 때 "api의 버전

보내려는 종류(kind)

추가적인 정보 (meta data: sample)

클래스의 스펙 (method : Run, view, save)프로퍼티 (name, color....ect)"이런 정보를 다 텍스트로 풀어써서 네크워크로 보내는 것이다. 그러면 시스템 B에서도 그 상세스펙을 보고 class를 잘 복원할 수 있다. 이게 바로 직렬화이다. 

 

YAML 포맷 특징?

-가독성 : 사람이 읽기 쉽도록 디자인, 해당되는 객체의 설계 도면을 적어둔 느낌

 

 

문법 구조?

- Key-Value 조합

- #을 사용하여 주석 처리

 

자료형?

-string (문자) : "로 감싸주는 게 좋다, 특히 숫자를 문자열로 써야할 때, YAML예약어와 겹칠때(y,yes,true..), 특수문자

-integer(정수): 일반 숫자나 16진수 표현 방식

-float(소수)

-exponential type(지수형)

-list : [ ]이나 한줄씩 나열 가능

  예시) 

     container:

          -name : busybox

            image: busybox:1.25

-Multi-line strings : \n처리하여 새로운 줄로 내려가게 하기

-구분선 : 하나의 yaml파일에 여러개의 도큐먼트 작성(---)

 

YAML파일은 vi에디터로 만들어보자

yaml 포맷으로 POD 파일 생성

# 파일생성
vi pod.yaml

# i 눌러서 인서트 모드

apiVersion: v1
kind: Pod
metadata:
	name: counter   #metadata 하위항목 들여쓰기
spec: 
	containers: 
    - name: count
      image busybox   # docker image
      args: [/bin/sh, -c, 'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done']
      
      # 1초 마다 시간 업데이트하는 거 busy box로 만듦
  
#esc키 눌러 명령 모드로 바꾼후 저장 나가기
:wq

# 내용 확인
cat pod.yaml

# file옵션으로(pod.yaml에 써있는대로) 적용해줘 
kubectl apply -f pod.yaml
# 하드 생성완료

#하드가 생성되고 실행이 잘되고 있는지 확인
kubectl get pod


# 이때 minikubes 실행된 상태여야한다
# system과 관련된 pod 확인
kubectl get pod -n kube-system

#전체 포드 확인
kubectl get pod -A

# 지정된 포드만 보기
kubectl get pod counter

#각각의 pod에 대한 자세한 정보, 과정까지 다 나옴
kubectl describe pod counter

# 각각의 하드에 대한 정보 볼 수 있는 또 다른 방법, describe보단 더 깔끔하고 ip number를 보여준다.
kubectl get pod -o wide

# 지속적으로 각각의 pod의 상태를 감시
kubectl get pod -w
ctrl + c 로 종료

#kubectl 사용하여 만든 busybox 로그확인(counter 하드이름도 입력)
kubectl logs counter

pod 자체에 접속하기, 삭제하기

# 직접 pod에 it 모드로 접속, 포드이름(counter), /접속할 쉘
kubectl exec -it counter /bin/sh


# pod 삭제하는 법(1) pod 이름으로 삭제
kubectl delete pod counter

# pod 삭제하는 법(2) 지정된 파일에서 설명하고 있는 pod 삭제
kubectl delete -f pod.yaml

# 잘 삭제되었는지 확인
kubectl get pod

Deployment 객체 

더보기

Deployment ?

-pod와 Replicaset(복제셋)에 대한 관리를 제공하는 단위

-yaml파일에서 정의

# 파일 생성
vi deployment.yaml

# i눌러서 인서트 모드로 변경 후 작성

apiVersion: apps/v1
kind: Deployment               #배포단위
metadata:
	name: nginx-deployment
    labels:
    	app: nginx
spec:
	replicas: 3                 # pod 인스턴스 갯수
    selector:
    	matchLabels:
        	app: nginx
    template:
    	metadata:
        	labels:
            	app: nginx
	spec:
      containers:                  # 컨테이너 정보
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
        

# 배포
kubectl apply -f deployment.yaml
# 돌아가고 있는 pod 확인
kubectl get pod     # 3개의 pod(replica)가 돌아가고 있다


# deployment 조회
kubectl get deployment   


# 이때 3개의 pod에서 20개의 pod로 늘려야할 때 scale 조절
kubectl scale deployment/nginx-deployment --replicas=20

# 확인작업
kubectl get deployment
kubectl get pod


------------------------------------------
삭제작업


# pod가 죽거나 응답이 없으면 관리하는 쿠버네티스 마스터에서 얘를 죽이고 새 pod만든다(auto-healing 기능)
# pod를 강제로 죽이고 다시 생성되는지 확인해보자

#pod 목록보고 죽일 pod 이름 복사해둘것
kubectl get pod
# 삭제
kubectl delete pod '복사한pod이름'
#pod 목록에 다시 생성됐나 확인
kubectl get pod


# deployment 삭제
kubectl delecte deployment nginx-deployment
# 삭제된 deployment에 속해있던 pod들 같이 삭제된 것 볼 수 있다
kubectl get pod

service

더보기

pod(쿠버네티스에서 배포한 어플리케이션)를 외부에서 접근하기 쉽게 추상화한 리소스,

 

다시 한번 쿠버네티스 구조를 떠올려보면 워크 노드에는 포트가 있고 컨테이너가 그 안에 들어있다. 각각의 pod마다 ip address가 할당이 되어있는데 이 ip address를 직접적으로 연결해 사용하기에는 pod가 다시 죽었다가 살아날 수 있어 비효율적이다. 그걸 피하기 위해 포드에 가상화된 리소스, 서비스라는 개념을 새로 만든다.

외부에서 연결할 때는 서비스까지만 연결하면 된다.

현재 실습에서는 가상머신을 사용하고 있고 network security group이라는 방화벽이 가상머신에 붙어있기 때문에...방화벽을 먼저 풀어줘야한다는 한계점이 있다

# 아까 만든 deployment 파일 들어가기
vi deployment.yaml
apiVersion: app/v1
kind: Deployment
metadata:
	name: ngnix-deployment
    labels:
    	app: nginx
spec:
	replicas: 3
    selector: 
    	matchLabels:
        	app: nginx
    template:
    	metadata:
        	labels:
            	app: nginx
        spec:
        	containers:
            -name: nginx
            	image: nginx:1.14.2
                ports:
                -containerPort: 80

저장하고 나오기

 


# 서비스를 만들어야하는 이유

생성된 Pod의 ip의 확인 접속 시도

# Pod의 ip 확인
kubectl get pod -o wide


curl -X GET <POD-IP> -vvv
ping <POD-IP>
# Private ip 주소라서 통신 불가능 (그 이유 아래에) 그래서 서비스를 만들어야하는 것이다
더보기

<사전지식-virtual network>

 

IPv4란?

xxx.xxx.xxx.xxx (100.10.10.15), 8 + 8 + 8 + 8 = 32bit

IP address는 총 32bit 숫자로 구성, (2^8 = 255, 즉 범위가 0~255까지가 4번)

이걸 IPv4방식이라고 한다.

즉 사용한 IP가 한정되어 있어 기기 수 만큼  충분하지 않아 다른 방법이 나온다.

 

(1) 8+8+8+8+8+8 로 주소체계를 2자리 늘리기 - 48bit 체계, IPv6방식,

또한 아래 이유로  IP address가 충분해졌다. 

(2) DHCP : ip address를 부여했다가 빼앗는 방식(많은 인원이 컴퓨터 사용하는 그룹에서 사용)

회사같은 곳에서는 IP address를 인원의 80%정도만 부여하고 사람들이 컴퓨터를 켜면 그때 ip address를 부여해줬다가 회수

(3) private network :

cmd창에 ipconfig 쳐보면 나의 ip 주소 체계를 볼 수 있다. 여기서 IPv4로 접근할 수 있다고 생각할 수 도있지만 안된다. 왜냐하면 프라이빗 네트워크(사설망) 기기마다 ip주소를 부여하기엔 부족해서 gateway(집에선 보통 인터넷공유기가 그 역할)가 공용 IP address(외부에서 접속가능한 퍼블릭 어드레스)는 따로 있고 private network(내부적으로 사용되는 네트워크)는 또 따로 있어서, 게이트 웨이를 거쳐서 퍼블릭 어드레스로 바꿔주고 다시 연결 받아야할땐 내부 어드레스 중 몇번이었는지 게이트웨이가 확인하고 보내줌.

 

그래서 사설망으로 direct로 요청하면 안되고 게이트웨이에 요청해야함


Docker는 퍼블릭 ip를 부여받고 안에 컨테이너는 privat IP를 할당받아 도커 안에서만 사용하게 되있는데, 그래서 이 사설네트워크는 퍼블릭IP로, 퍼블릭 IP는 사설 네트워크로 바꿔주는 명령이 필요하다.

 

 

 

 


서비스 만들기

 

 

vi service.yaml

----------------------------------------------------------

apiVersion: app/v1
kind: Service
metadata:
	name: my-ngnix
    labels:
    	run: my-nginx
spec:
	type: NodePort    # 노트포트는 도커를 열어서 외부에서 접속 가능하게 해주는 것
    ports:
    -port: 80
     protocol: TCP
    selector:
    	app: nginx
        
----------------------------------------------------------

kubectl apply -f service.yaml

kubectl get service    # port 80:<port> 숫자확인
curl -X GET $(minikube ip):<PORT> # 외부에서도 POD에 접속가능 확인

 

 

 

-유투브 따배쿠 쿠바네티스 강좌 추천 -


정리

 

-docker  파일 만들어 docker image만들 수 있고 이런 것들은 컨테이너로 만들어 local pc나 docker hub 등에서 push하여 공유할 수 있다.

-그리고 컨테이너를 관리하는 쿠버네티스 에서는 컨테이너를 pod라는 개념안에 보관한다. pod가 응답이 없거나 죽으면 쿠버네티스 마스터가 죽이고 새로 생성을 한다. pod는 yaml 양식의 파일로 직접만들거나 deployment 로 여러개를 인스턴스로 만들 수 있다.

+ Recent posts