Docker 기초 메모 

# 1) :card_box: docker에 대하여
### 1-1) docker란?
- 컨테이너 형 가상환경 플랫폼
- 가상환경을 작성・배포・실행 할수 있음
- 여러 환경을 동시에 구축 및 관리가 가능함

### 1-2) docker의 장점
- 특정 OS에 의존이 없어 도입하기가 용이
- 안건별로 다른 환경을 구축가능하다 → 특정 pc에 의존하지 않는다
- 미들웨어 도입・새로운 인프라 환경의 테스트가 각 pc에서 가능하다
- 언어나 툴의 버전업 테스트가 용이하다
- 모든 팀원이 각자의 pc로 디버그를 할 수 있다

※ 쉽게말해 , 개발환경이 다른 사용자들끼리 하나의 컨테이너로 묶어 일관된 실행환경을 보장함

### 1-3) docker의 컨테이너
- 인프라 환경을 정리한 것
    -어플리케이션의 실행 모듈, 미들웨어 및 라이브러리 ,  운영체제와 인터넷 등의 인프라 환경설정
- ***도커 이미지***를 기반으로 작성 (도커이미지란 , 컨테이너를 실행하기 위한 설계도와 유사)
- docker hub 등의 레포지토리로 공유

### 1-4) 가상머신과 컨테이너의 차이

| 가상머신 ( VirtualBox 등 기반 ) | 컨테이너 ( docker 등 기반 ) |
|---------|--------|
| 어떤 OS라도 기본적으로 가능 | 베이스 OS는 어디까지나 linux|
| 각 가상 머신에는 독자적인 OS가 탑재| OS환경을 공유 (가상머신보다 리소스 이용이 적다)|
| 디스크 용량을 점유한다 | 최소한의 라이브러리와 툴만을 포함 ( 기동이 더 빠름 ) |
| OS업데이트, 패치적용을 독자적으로 함   | 컨테이너 박스만 갱신이 필요 (보수가 편함) |

### 1-5) docker의 흐름
1 . ***`build` : 도커이미지를 작성하는 기능***
- 기능
    - docker 이미지를 비롯한 실행에 필요한 파일들이 저장된 디렉토리
    - 일반적으로 Dockerfile이라는 설정 파일로 만들어 짐
    - 여러 이미지를 중첩시키는 것이 가능
-  Automated Build
    -  docker Hub를 통해 github나 bitbacket등과 연계가능
    -  깃허브 상에서 도커파일을 관리하여 도커이미지를 자동생성 가능
- docker 이미지 변경방지 및 취약성 스캔
    - Docker Content Trust
        - 이미지 제공자를 검증하는 기능
        - 변경되어 있는 이미지를 무효화함
    - Docker Security Scanning 
        - 도커이미지를 스캔하여 취약성이 없는지를 확인
        - 이미지의 안전성을 확인 
        
2 .  ***`ship` : 도커이미지를 공유하는 기능***
- 기능
    - 도커이미지는 도커 레지스트리에서 공유됨
    - 개인적으로 만든 이미지를 docker hub에서 공개 및 공유가능 

3 . ***`run` : docker 컨테이너를 기동하는 기능***
- 기능
    - 이미지를 기반으로 컨테이너 작성
    - 하나의 이미지로 복수의 컨테이너 작성 가능
    - docker가 설치되어 있다면 어디서든 컨테이너 실행가능
    - docker컨테이너 실행 (컨테이너의 기동・정지・파기)
        
※ 즉 , 생성 (build) -> 보관 (push) -> 실행 (run)의 절차를 거친다 

### 1-6) docker의 컴포넌트
- ***Docker Engine***
    - 도커 코어 기능
    - 도커 이미지 생성
    - 도커 커맨드의 실행 ( 컨테이너 기동 등 )
- ***Docker Registry***
    - 도커 이미지를 공유・공개 하기위한 기능
    - docker hub에서도 이용됨
- ***Docker Compose***
    - 어플리케이션 실행 환경을 구성하는 여러 컨테이너를 일괄적 관리
    - 어러 컨테이너 구성정보를 코드를 정의
- ***Docker Machine***
    - 커맨드를 통해 실행환경을 자동적으로 생성 (virtual Box , Amazon Web Service EC2 등  )
- ***Docker Swarm***
    - 여러 docker호스트를 클러스터화(군집화) 시켜서 관리
    - manager : 클러스터의 관리 및 API제공
    - node : docker 컨테이너를 실행하는 역할
    - 오픈소스 `kubernates`도 이용가능

<br>
<hr>

# 2) :keyboard: docker의 기본조작
### 2-1) docker 데몬 기동
```
systemctl start docker
service docker start
```
※ "Redirecting to ~ docker.service" 라고 메세지가 뜨면 정상작동
```
systemctl enable docker
chkconfig docker on
```
※ docker를 부트시에 자동으로 기동시키려면 다음과 같이 실행
- 참고로 `systemctl`은 서비스 기동・정지・상태확인의 역할을, `chkconfig`는 OS기동시에 같이 기동될 서비스 등록 및 삭제의 역할을 함

### 2-2) 도커 유틸 커맨드

```
docker version       # 버전 확인
docker system info   # 실행환경 확인
docker system df     # 디스크 이용상황 확인
```


### 2-3) 웹 서버 기동
1 . ***이미지 다운로드***
```
docker image pull [ 옵션 ] 이미지명[:태그명] # 기본적인 이미지 습득

docker pull [ 이미지 ]
```
※ 여기서 본인은 이미지를 nginx를 사용. (apache와 express 등과 같은 웹 서버)

- 주 된 옵션
    - `a`, `--all-tags=false` : 레포지토리에서 태그가 붙은 모든 이미지를 다운로드
    - `--disable-content-trust=true` : 이미지의 인증을 스킵
<br>

2 . ***다운로드한 이미지 확인***
```
docker image ls
```
※ 레포지토리와 이미지id 등을  확인 가능

<br>

3 . ***컨테이너 생성***
```
docker container run --name [ 컨테이너 이름 ] [ 옵션 ] [ 이미지 ]:[ 태그 ]

docker create [ 옵션 ] [ 이미지 ] [ 커맨드 ] [ 인수 ] # 위에와 다르게 컨테이너 실행이 아닌 생성만 행함



# nginx 를 사용할시 다음과 같음
docker container run --name webserver -d-p 80:80 nginx
# 컨테이너 기동 커맨드 , 컨테이너 이름 지정 , 옵션 , 도커이미지 이름 순으로 씀
```
※ `-d` `-p`는 각각 "디터치모드(백그라운드로 실행하여 다른 옵션과 동시에 사용하기 위함)" , "호스트:포트 번호" 설정 옵션임

- 옵션
    - `attach` `-a` : 표준출력 표준에러 열음
    - `interactive` `-i` : 컨테이너 표준입력을 열음
    - `tty` `-t` : 표준 디바이스를 사용
    - `-detach` `-d ` : 컨테이너를 생성할때 백그라운드에서 기동시킨다
    
<br>

4 . ***컨테이너 동작상황 확인***
```
docker container ls
```
※ 컨테이너id , 도커이미지 , 컨테이너 이름 , 등이 표시된다.

<br>

5 . ***컨테이너 정지와 기동***
```
docker stop [ 컨테이너 이름 ]     # 컨테이너 정지
docker start [ 컨테이너 이름 ]    # 컨테이너 기동

docker container stop [ 옵션 ] [ 컨테이너이름 또는 컨테이너id ]
docker container start [ 옵션 ] [ 컨테이너id 또는 컨테이너이름 ]
```
※ 브라우저 localhost에 엑세스시 정지시에는 에러, 기동시에는 출력이 됨

- 옵션
    - `attach` `-a` :  표준출력・표준에러를 열음
    - `-interactive` `-i` : 컨테이너 표준입력을 열음

<br>

### 2-4) 실행중인 컨테이너 상호작용

1 . ***이미지 다운로드*** 
※ 먼저 리눅스의 디스트리뷰션 중 하나인 `ubuntu`를 다운로드
```
docker image pull ubuntu:18.04
```

<br>

2 . ***컨테이너 생성*** 

```
docker container run --name my-ubuntu -it -d ubuntu:18.04
```
※ 컨테이너 기동 커맨드 , 컨테이너 이름 지정 , 옵션 , 도커이미지 이름:태그(버전) 순으로 씀
※ `-i` `-t`는 각각 표준입력 열기, tty(표준입력으로 설정된 단말 디바이스) 적용을 뜻함
※ `-it`를 통해 터미널에서 컨테이너를 실행하는 것이 가능해짐 ( 기본적인 옵션이라고 생각 )
※ `-d` 는 상술했던대로 디터치모드

<br>

3 . ***도커 인터페이스***
```
docker exec -it [ 옵션 ] [ 컨테이너이름 또는 컨테이너 id ] [커맨드]        # 가동중인 컨테이너 접속

docker container attach [ 옵션 ] [ 컨테이너 이름 또는 컨테이너id ]       # 가동중인 컨테이너에 접속 (우분투 터미널 실행 / 커맨드 `exit`으로 탈출)

docker exec -it [ 컨테이너 이름 ] /bin/bash   # 사실상 attach보다 이걸 쓰는게 더 좋음

```
※ `docker exec`와 `docker attach`의 차이
| docker exec | docker attach |
|--|--|
| 백그라운드 컨테이너 호출 | 백그라운드 컨테이너를 포그라운드로 실행 |
| 커맨드를 실행할때마다 호출해야함 | 연속적으로 커맨드 입력 및 실행 가능 |
| 컨테이너 정지 안됨 | `exit` 또는 `ctrl + c` 를 통해 컨테이너가 정지 |
|  | + 컨테이너에서 기동하고있는 PID=1의 표준입출력에 접속 |

※ 컨테이너는 격리된 환경임으로 단순 리눅스 명령어로만 접근 불가하며 프로세스에 접근하기 위해서는 위의 도커 인터페이스를 사용할 필요가 있다
※ attach 상태에서 탈출하면 컨테이너가 stop상태가 되므로 `docker start [ 컨테이너 이름 ]` 커맨드로 컨테이너 재기동


- 옵션
    - `user` `-u` : 유저를 지정
    - `interactive` `-i` : 컨테이너 표준입력을 열음
    - `tty` `-t` : 표준 디바이스를 사용
    - `-detach` `-d ` : 컨테이너를 생성할때 백그라운드에서 기동시킨다

<br>

### 2-5) 컨테이너 및 이미지 삭제

1 . ***컨테이너 삭제***

```
docker stop [ 컨테이너 이름 ]
docker container rm [ 옵션 ] [ 컨테이너 이름 ]
```
※ 삭제할때는 먼저 stop상태로 만들어야 함

<br>

2 . ***도커이미지 삭제*** 

```
docker image rm [옵션] [ 이미지  이름 ]
```
- 옵션
    - `-f` `-force` : 강제 삭제
    - `--no-prune` : 의존 관계에 있던 중간 이미지를 삭제하지 않음
<br>

3 . ***불필요한 이미지・컨테이너 일괄삭제***
```
docker system prune    # 불필요한 이미지・컨테이너를 일괄 삭제
docker image prune     # 불필요한 이미지만을 삭제
docker container prune # 불필요한 컨테이너만을 삭제 
```

※ `docker run [ 이미지 ]` 를 하게되면 무명 컨테이너가 남기 때문에 이미지 삭제시 `-f`가 필요해짐
※ `docker container prune` 를 하게되면 무명의 컨테이너가 삭제되기 때문에 그냥 이미지를 삭제 할 수 있게됨

<br>

### 2-6) docker에서 os를 기동시키는 방법

```
docker run -it [OS명][:태그]
```
- 기동하고 있는 os에서 빠져나오는 방법
    - `exit` `ctrl + c` : 컨테이너가 종료됨
    - `ctrl + p` `ctrl + q` :  컨테이너가 종료되지 않음 (다시 attach로 접속될 가능성 있음 )

<br>

### 2-7) 그 외 컨테이너 조작 커맨드

```
docker container restart [ 컨테이너이름 또는 컨테이너id ]  # 컨테이너 재기동 
docker container pause [ 컨테이너이름 또는 컨테이너id ]    # 컨테이너 중단 
docker container unpause [ 컨테이너이름 또는 컨테이너id ]  # 컨테이너 재개
```
<br>
<hr>

# 3) :clipboard: docker 이미지 작성
### 3-1) 도커 이미지 작성방법
- 컨테이너에서 독자적으로 이미지를 만듦
- 공개 이미지를 이용하여 컨테이너를 만들고 그곳에 덧붙여서 오리지널 이미지를 만드는 케이스도 많음
- 일반적으로 Dockerfile을 이용하여 작성

### 3-2) 도커 이미지 만들기 ① ( Dockerfile을 통한 )
1 . ***도커 이미지를 만드는 과정***
- 이미지 ***취득***(`docker image pull`) ⇒ Dockerfile ***작성*** ⇒ 도커 이미지 ***생성*** (`docker image build`)

2 . ***도커 이미지를 만드는 이유***
- 개발 환경을 구축하기 위함이 크다
    - 유저 추가 및 권한 설정 (root , 일반유저)
    - web 서버 , 데이터베이스 , 개발언어 (nignx , MYSQL , php)
    - DB초기 데이터 , 베이스가 되는 소스코드 , 설정 파일  등 

3 . ***Dockerfile의 기본구문***
```
[ 커맨드명 ] [ 파라미터 ] 
```
※커맨드명은 대문자로 적는다
    - `FROM` : 베이스 도커이미지
    - `CMD` : `docker run`일때 실행되는 커맨드

4 . ***이미지 생성***

```
docker image build -t [ 이미지명 ] [ 디렉토리명(도커파일 존재) ]
```
※ 홈 디렉토리로 체인지 디렉토리 한 후에 커맨드 실행

### 3-3) 도커 이미지 업로드 
1 . ***업로드 처리 흐름***
- docker 이미지 태그 붙이기 ⇒ docker Hub에 로그인 ⇒ docker 이미지 업로드 ⇒ docker Hub 로그아웃

    - 태그 붙이기
    ```
    docker image tag [ 베이스이미지명 ] [ dockerhub유저명 ]/[ 이미지명 ][:태그]
    ```
    - docker Hub에 로그인
    ```
    docker login
    ``` 
    - docker 이미지 업로드
    ```
    docker image push [ dockerhub유저명 ]/[ 이미지명 ][:태그]
    ```
    - docker Hub 로그아웃
    ```
    docker logout
    ```
     
<br>

- 이후에 docker Hub 브라우저(혹은 데스크톱 등)에서 업로드를 확인

<br>

### 3-4) 도커 이미지 만들기 ② (요소 복사)

1 . ***컨테이너 생성***
```
docker container run --name [ 컨테이너이름지정 ] -it -d [ 이미지명 ]  # 컨테이너 생성 및 기동
```

2 . ***컨테이너 복사***

```
docker container cp [ 피복사요소 ] [ 컨테이너이름 ]:[패스] 
```
※ 컨테이너와 컨테이너  또는 컨테이너와 OS끼리는 서로 복사가 가능함
※ 피복사요소는 주로 파일 또는 디렉토리가 될수있음


3 . ***컨테이너 내 변경점 확인(생략해도 됨)***

```
docker container diff [ 컨테이너 이름 ]
```
※ A는 파일추가 C는 파일 갱신  D는 파일 삭제

4 . ***이미지 작성***

```
docker container commit [ 옵션 ] [ 컨테이너 명 ] [ docker hub 유저명 ]/[ 이미지 명 ][:태그명]
```

- `-a "작성자이름"` : 작성자를 지정함  

5 . ***이미지 업로드***

```
docker image push [ docker hub 유저명 ] [ 이미지명 ][: 태그명 ]   # 방법은 Dockerfile 때랑 동일
```
- 방법은 `Dockerfile`로 도커이미지 만들때와 다르지 않다. 
- 안 먹히면 `docker push` 로 해보자 그래도 안 되면 모르겠다

<br>

### 3-5) 작성한 이미지 다운로드
```
docker image pull [ 이미지 ]
```
- 당연한 이야기지만 통상적인 도커이미지 `pull` 에서 크게 벗어나지 않음
- 주의할 점은 보통 `docker hub ID/이미지명:태그` 로 저장할테니 [ 이미지 ]에 잘 맞춰 적으면 됨

<br>

### 3-6) 로컬환경에 파일 저장 및 불러오기

1 . ***도커이미지 로컬 저장 및 불러오기*** 

```
docker image save -o [ 파일명.tar ] [ 이미지이름 ] # 로컬 환경에 이미지 저장
docker image load -i [ 파일명.tar ]              # 로컬 데이터룰 불러오기
```
※ tar 형식으로 저장되고 불러와짐
- 옵션
    - `-o` : tar 파일로 저장
    - `-i` : tar 파일로 부터 읽어냄

2 . ***컨테이너 로컬 저장 및 불러오기***

```
docker container export [ 컨테이너이름 ] > [ 파일명.tar ] # 로컬환경에 저장
cat [ 파일명.tar ] | docker image import - [ 이미지명 ]  # 로컬환경에서 불러오기

docker container import [파일명.tar] - [이미지명][:태그명] # 이것도 import지만 기본적으로는 윗 구문을 더 많이 씀
```
※ 이미지와 마찬가지로 tar형식으로 저장되고 불러와짐
※ 정확히 말하자면 `import` 로는 컨테이너 생성은 안되고 컨테이너를 저장하는 export와 짝을 이룰 뿐임 (컨테이너 생성을 위해서는 생성된 이미지를 바탕으로 다시 생성할 필요 있음)

# 4) :pencil2: Dockerfile을 편집

### 4-1) ***Dockerfile 구조***
1 . ***도커 파일이란?***
- 도커 상에서 작동시키는 컨테이너 구성정보를 기술하는 파일
- `docker build` 커맨드는 Dockerfile을 기반으로 이미지를 만듦
- 기본적인 구문으로는 다음과 같다
    ```
    # 코멘트
    [ 명령 ] [ 인수 ]
    ```

<br>
    
2 . ***도커 파일에 기술되는 것***
- 베이스가 되는 도커이미지
- 도커 컨테이너 안에서 기동되는 조작(커맨드)
- 환경변수 등 여러 설정
- 도커 컨테이너 안에서 동작 시켜두는 데몬 실행 

<br>


### 4-2) DockerFile 명령 

1 . ***주된 Dockerfile 명령***
| 명령 | 기능 |
|--|--|
| `FROM`        | 베이스 이미지 지정         |
| `RUN`         | 커맨드 실행               |
| `CMD`         | 컨테이너 기본 실행 커맨드 | 
| `ENTRYPOINT`  | 컨테이너 실행 커맨드      |
| `LABEL`       | key = value를 통한 문서화 |
| `ENV`         | 컨테이너 실행시 사용할 환경변수 설정   |
| `ARG`         | 도커 파일 내 변수 설정      |
| `ADD`         | 파일 및 디렉토리 추가 및 압축풀기 기능  |
| `COPY`        | 이미지 쪽으로 파일/디렉토리 복사 | 
| `EXPOSE`      | 포트 설정                |
| `VOLUME`      | 이미지에 볼륨을 할당   |
| `USER`        | 이미지 실행이나 도커 명령(`RUN` `CMD` `ENTRYPOINT`) 을 내릴 유저 지정 | 
| `WORKDIR`     |`RUN` `CMD` `ENTRYPOINT` `COPY` `ADD`명령을 실행하기 위한 워크 디렉토리 지정|
| `SHELL`       | 기본값 쉘 지정             |
| `ONBUILD`     | 빌드 실행 후에 실행되는 명령 |
| `STOPSIGNAL`  | 시스템 콜 시그널           |
| `HEALTHCHECK` | 컨테이너 상태 체크          |


- 서식 및 사용례
    - `FROM [이미지명]:[태그]`
        - FROM ubuntu'latest : 우분투 최신버전을 베이스 이미지로 설정
    - `Run [ ["커맨드"] ]`  `RUN [커맨드]`
        - RUN ["apt-get","install","-y","-q","nginx"] : nginx 인스톨 (Exec형식)
        - RUN apt-get install -y -q nginx : nginx 인스톨 (shell형식)
    - `CMD [ ["커맨드"] ]` `CMD [ 커맨드 ]`  
        - CMD ["nginx","-g","daemon off;"] : nginx의 데몬을 기동 ( EXEC형식 )
        - CMD nginx -g ‘daemon off;’ : nginx의 데몬을 기동 ( shell형 )
    - `ENTRYPOINT [ ["커맨드"] ]` `ENTRYPOINT [ 커맨드 ]` 
        - ENTRYPOINT ["nginx","-g","daemon off;"] : nginx의 데몬을 기동 ( EXEC형식 )
        - ENTRYPOINT nginx -g ‘daemon off;’ : nginx의 데몬을 기동 ( shell형 )
    - `LABEL  [ key ]=[ value ]`
        - LABEL title = "webapp" : "title" 이라는 key에 "webapp"이라는 값 부여
    - `ENV [ key ]=[ value ]`
        - ENV name "KIM" : "네임이라는 변수에" "kim"이라는 값 부여
   - `ARG  [ key ]=[ value ]`
        - ARG DBPassWd="1234567890" : DBPassWd라는 변수에 "1234567890" 이라는 값 부여 
    - `ADD [ 호스트 파일경로 ] [ 이미지 파일 경로 ] `
        - ADD website.tar /var/www/html` : website.tar을 /var/www/html쪽에 복사
    - `COPY [호스트의 파일경로] [이미지 파일 경로 ]`
        - COPY index.html /val/www/html : "index.html"을 이미지 "/val/www/html"쪽으로 복사
    - `EXPOSE [ 포트번호 ]`
        - EXPOSE 80 : 컨테이너의 포트를 80번으로 설정
    - `VOLUME [ "/할당 포인트" ]`
        - VOLUME "/var/log" : 자세한 내용은 볼륨항목 참조
    - `USER [ 유저명 또는 UID ]`
        - USER "KIM" : KIM이라는 유저에게 이미지 실행 및 도커파일 명령권 부여
    - `WORKDIR [ 디렉토리 경로 ]`
        - WORKDIR /first : /first 경로를 워크디렉토리로 설정
   - `SHELL ["쉘 경로,"옵션"]`
        - SHELL [ "/bin/bash","-C" ] : "/bin/bash" 문자열 경로를 기본값 쉘로 설정하도록 실행  
    


※ `RUN` `CMD` `ENTRYPOINT`는 문법은 비슷하지만 `RUN`은 이미지 인스톨 및 설정 시 , `CMD`는 디폴트로 실행되는 가변적인 커맨드를 , `ENTRYPOINT`는 고정적으로 실행되는 커맨드를 설정할수 있음.  
※ `LABEL` `ENV` `ARG`는 모두 key=value를 가지지만 `label`은 기능에 영향받지 않고, `env`는 컨테이너 및 도커파일에 영향을 주고, `ARG`는 도커파일에만 영향을 줌 
(다만 env는 이미지에 남기때문에 DB 패스워드 등 민감한 사항 등은 이미지에 남지않는 ARG를 권장)
※ `ADD` `COPY` 둘다 파일을 이미지쪽으로 복사하는 것처럼 보이지만 `add`는 외부 url에서 다운하는 기능과 압축 해제의 기능도 가지고 있어서 왠만하면 안정성이 높은 `copy`쪽이 선호됨 

<br>

2 . ***패키지 관리 시스템***
- YUM (***Y***ellowdog ***U***pdate ***M***odified)
    - centOS , Fedra 등 RedHat 계열 시스템
    - 최근 버전에서는 DNF(Dandified Yum)가 뒤를 이음
- APT (***A***dvanced ***P***ackaging ***T***ool)
    - Ubuntu , Debian 등 Debian 계열 시스템 

<br>

3 . ***`ONBUILD`, 자식이미지에서 실행되는 명령***
- `ONBUILD` 
    - 다음에 빌드될 때 실행하는 커맨드를 이미지 안에 설정
    - `ONBUILD`는 자식 이미지를 연계 후 빌드 했을때 실행됨 (`ONBUILD`를 포함한 부모 이미지에서 빌드했을때는 실행 안됨 )
    - 용례
        -  베이스 이미지에 OS 인스톨 및 환경구축
        -  개발 환경을 deploy하는 명령을 넣음 (`COPY` `ADD`)
        -  코딩한 내용을 베이스 이미지를 기반으로 신규 이미지 작성 가능
    - 서식
        - `ONBUILD [명령] [인수]`
        - `ONBUILD ADD website.tar /var/www/html` : 자식 이미지에서 빌드 될시 website.tar을 /var/www/html 이미지에 복사


<br>
<hr>

# 5) :satellite: 볼륨과 네트워크
### 5-1) 개요
1 . ***여러 컨테이너를 운영하기 위해서는*** 
- 여러 컨테이너가 존재하며(Linux , webServer , SQL 등) 컨테이너 끼리 연결시킬 필요가 있음
- 영속데이터를 다룰 필요가 있음

<br>
 
2 . ***영속데이터***
- 영속데이터란?
    - 시스템 운영시에 생성 및 축적되는 데이터 (유저 인증시의 엑세스 기록 , 고객정보, 매출정보 등)
    - 시스템 가동시간에 따라 증감함
    - 프로그램을 종료해도 저장소에 기억됨
    - 중요 데이터이기 때문에 백업 및 복구가 가능해야 
- 영속데이터 다루는 방법
    - MYSQL등의 데이터베이스 컨테이너를 사용
    - `VOLUME`을 사용하는 방법

<br>

3 . ***Docker의 네트워크***
- 컨테이너 간의 네트워크는 도커의 리소스로써 관리됨
- 디폴트 네트워트와 생성가능한 네트워크가 있음
- 생성하는 시스템에 응하여 나눠 사용할 필요가 있음

<br>

4 . ***BUSYBOX***
- 특징
    - 표준 UNIX코드에서 중요한 여러 프로그램을 단일 실행 파일로 눌러담아 제공 (경량 유틸리티)
    - 임베디드 리눅스 , 도커 등에서 널리 사용되고 있음
    - 실상은 하나의 커맨드에 불과함
- 내부구성 
    - 어플렛(임베디드 프로그램) : 커맨드 기능에 해당하는 것
        - `init` `ping` `cp` `ls` `httpd` `vi`
    - libbb : 어플렛간 사용되는 함수를 정의한 것
- 도커에서 busybox의 쓰임새
    - VOLUME 작성
        - VOLUME 작성시 잠정적(일시적)으로 이용
        - 컨테이너를 만들었을시 삭제함
    - 네트워크
        - 네트워크 테스트
    - 그 외
        - 멀티호스트 환경 구축
        - 약간의 리눅스 기능 사용 (보통의 리눅스 환경보다 커맨드가 제한됨) 
- BUSYBOX 에서 사용할수 있는 주된 커맨드
    - 쉘 에디터
        - `vi` `sed` `awk`
    - 시스템 관리 커맨드
        - `coreutils` `tar` `bzip`
    - 각종 데몬
        - `cron` `httpd`
    - 네트워크 커맨드
        - `ping` `ipconfig` `wget`
    - 유저 관리 커맨드
        - `login` `su` `useradd`
    - SELinux 관리 커맨드
        - `load_policy` `restorecon`

- busybox 컨테이너 생성

```
docker run -it --rm busybox
```
※ `-rm` 은 자동적으로 컨테이너가 삭제되는 옵션 `-it`은 위에 컨테이너 생성 참조
※ busybox가 인스톨 되지 않았을 경우에도 해당 커맨드로 인스톨 가능
※ 경로가 `/ #` 이 되었다면 성공


<br>

### 5-2) VOLUME
1 .  ***VOLUME이란?***
- 데이터를 영속화 할수있는 곳
- 컨테이너 본체에 마운트(외부 저장소 등을 디렉토리로써 접속)하여 사용
- 여러 컨테이너에서 공유가능
- 볼륨은 컨테이너에서 분리되어 있기 때문에 컨테이너에 문제가 생겨도 데이터만은 남게 됨
- 저장된 볼륨은 다른 컨테이너에서 마운트하여 사용가능
- 마운트 된 볼륨은 디렉토리로써 취급됨
- 파일의 작성 및 불러오기가 가능

<br>

2 . ***볼륨 관련 커맨드***

- 볼륨생성

```
docker volume create [ 볼륨명 ]
```

- 볼륨 일람

```
docker volume ls  
```

- 볼륨의 상세정보를 표시

```
docker volume inspect [ 볼륨명 ] 
```

- 볼륨 삭제

```
docker volume rm [ 볼륨명 ]
 ```

- 볼륨을 청소
```
docker volume prune
```

<br>

3 . ***도커커맨드를 작성하여 컨테이너에 볼륨을 마운트 하는 방법***


```
docker run -v [ 볼륨명 ]:[ 디렉토리명 ]

docker run -v [ 볼륨명 ]:/[ 마운트 할 경로 ] --rm -it [OS의 이미지]          # OS에 마운트
```

※ 볼륨이 있는것이 전제사항이다.

<br>

4 .  ***도커파일로 컨테이너에 볼륨을 마운트 하는 방법***

- 도커파일 작성 순서
    - 이미지 작성
        - OS를 기동 (여기서는 busybox 사용)
        - 기동한 OS내 디렉토리를 볼륨으로 지정
    - 컨테이너 생성・기동・삭제
        - 컨테이너를 작성・실행함
        - 작성한 컨테이너를 삭제한다
    - 볼륨이 잔류
        - 작성한 다른 컨테이너에 접속
        - 내용을 확인

※ 사실상 「컨테이너 생성・기동・삭제」단계에서 끝이지만 확인 방법까지 기재

- 생성 예

    - 1. 이미지(도커파일) 작성

        ```
        FROM busy box
        
        RUN mkdir /test
        
        Run echo "Test make Volume" > /test/testText.txt
        
        VOLUME /test
        ```
    
    - 2 . 컨테이너 생성・기동・삭제
    
        ```
        docker run --it -rm -v [볼륨명]:/test test-sample
        
        exit           # 컨테이너 생성 뒤 나가는 것으로 삭제 `-rm`
        ```
    
    - 3 . 볼륨 잔류 확인
        ```
        docker run --it -rm -v [볼륨명]:/tmp busybox # 다른 컨테이너를 만든 뒤 볼륨의 잔류 확인
        ```

<br>

### 5-3) docker 네트워크의 구조

1 . ***전제지식 및 개요***
- NIC
    - 네트워크 카드의 약자
    - 컴퓨터 등의 기기를 통신 네트워크(LAN)에 접속시키기 위한 카드형 확장장치
    - Linux에서는 `eth0` 라는 디바이스로 인식시킴
- 브릿지 접속
    - 다른 네트워크 세그먼트끼리 접속하는 것
    - 소프트웨어적 방식 및 하드웨어적 방식 두가지가 있음
- 도커의 네트워크 구성
    - ech0 (물리 NIC) ⇒　docker0(가상 브릿지)　⇒ vethXX(가상NIC) ⇒ 컨테이너A (ech0)
    - ...................................................................................... ⇒ vethXX(가상NIC) ⇒ 컨테이너B (ech0)
-  도커가 인스톨 된 Linux
    -  docker0
        -  도커 기동시 자동으로 생성되는 가상 브릿지
        -  서버 물리 NIC가 docker0라는 가상 브릿지에 접속됨
    -  컨테이너의 eth0
        - 프라이빗 IP주소가 할당됨
        - 호스트 OS에 의해 작성된 가상 NIC디바이스
- 도커 네트워크의 기능
    - 컨테이너간 통신 제어
    - 같은 네트워크에 연결된 컨테이너 끼리는 이름으로 통신제어
    - 필요에 따라 외부로의 네트워크 통로를 제어

<br>

2 .  ***컨터이너와 외부통신***
- docker0에서 NAPT를 이용중
- NAPT란?
    - Network Address Port Translation의 약자
    - 프라이빗 IP주소와 글로벌 IP주소를 변환하는 기술
    - 포트번호의 변환도 함
    - 복수의 프라이빗 IP주소를 상호변환함
    - 하나의 글로벌 IP주소로 복수의 머신 접속가능
- 외부통신 흐름
    - 외부에서 엑세스 ⇒ NAPT에서 ip주소 및 포트번호 변환 ⇒ 브릿지에서 컨테이너 선택 ⇒ 대상 컨테이너 엑세스 

<br>

3 . ***디폴트 네트워크***
- `none` `host` `bridge` 가 있음 (도커의 일부로 설정 된 네트워크 드라이버)
- 컨테이너는 이 중 하나의 네트워크를 가짐 (특히 지정하지 않는다면 `bridge`가 할당됨)
- `none` 네트워크
    - 네트워크 드라이버는 존재하지 않음
    - 네트워크 접속을 필요로 하지 않는 컨테이너 작성에 사용
- `host` 네트워크
    - docker 호스트와 같은 네트워크에 겹쳐 사용되는 드라이버
    - 호스트와 동일한 네트워크 인터페이스 및 IP주소를 가짐
- `bridge` 네트워크
    - docker를 사용할 때 기본적으로 사용되는 드라이버
    - Linux 커널의 브릿지 네트워크를 사용하기 위한 기능 (위의 도커 네트워크 구성 참조)

<br>

### 5-4) docker 네트워크 커맨드

1 .  ***도커 네트워크 일람 취득***
```
docker network ls [ 옵션 ]
```
- 옵션
    - `-f=[]` `--filter` : 출력을 필터링 
    - `--no-trunc` : 상세내용 출력
    - `--quit` `-q` : 네트워크 아이디만 출력

※ 네트워크 아이디 ,이름 ,드라이버 등의 정보를 볼 수 있음

<br>

2 . ***도커 네트워크 생성***
```
docker network create [ 옵션 ] [ 네트워크이름 ]
```
- 옵션
    - `-d` `--driver` : 네트워크 드라이버 종류(디폴트 값 : `bridge`)
    - `--ip-range` : 컨테이너에 할당할 IP주소의 범위
    - `--label` : 네트워크에 설정할 라벨

<br>

3 . ***도커 네트워크 상세 표시***
```
docker network inspect [ 옵션 ] [ 네트워크 이름 ]
```

<br>
    
4 . ***도커 네트워크 접속***
```
docker network connect [ 옵션 ] [ 네트워크 이름 ] [ 컨테이너 ]
```
- 옵션
    - `--link` : 다른 컨테이너와 연결
    - `--ip` : IP주소
    - `--alias` : 얼라이어스 이름

<br>
    
5 . ***도커 네트워크 접속 끊기***
```
docker network disconnect [ 옵션 ] [ 네트워크 이름 ] [ 컨테이너 ]
```
- 옵션
    - `-f` `--force` : 강제끊기

<br>

6 . ***네트워크 삭제***
```
docker network rm [ 옵션 ] [ 네트워크 이름 ]
```

<br>
    
7 . ***네트워크를 지정한 컨테이너 기동***
```
docker run -d -p 80:80 --name=[ 컨테이너 이름 ] --net=[ 네트워크 이름 ] [ 이미지 ]
```

<br>