- 컨테이너 표준 기술. cgroup, namespace에 대한 표준 제정
chroot
- 일반 사용자가 컨테이너 내부에 들어갔을경우 슈퍼유저인 root로 작업할 수 있도록 해준다.
cgroup
- namespace를 통해 구획이 나뉜 각 컨테이너별로 별도의 자원 사용량을 제공하는 것 (cpu,ram)
namespace
- 각각의 컨테이너별로 별도의 작업공간을 제공하고 각 컨테이너 별로 서로간에 영향을 끼치지 않도록 구획을 나눈다.
- Kubelet 이 컨테이너를 제어할 수 있도록 해주는 인터페이스
일반 리눅스에서의 namespace
- httpd : ftp : nfs -> 각 1개씩만 서로 구분 가능(추가적으로 설치 불가)
도커(컨테이너)에서의 namespace
- 컨테이너(1111-httpd) : 컨테이너(1112-httpd) : 컨테이너(1113-httpd) -> 추가 설치 가능
k8s에서의 namespace
- 각 사용자별로 별도의 작업 공간을 제공
- 쿠버네티스는 컨테이너(오케스트레이션) 룰 . 일반적으로 오케스트레이션은 컨테이너 클러스터 환경에서 이루어지게 된다.
- 애플리케이션은 배포한다.
- 시스템(서버,네트워크,볼륨)은 프로비저닝한다
- 배포와 프로비전은 일반적으로 여러 컨테이너, 서버, 네트워크, 볼륨 등을 연계하여 구성해야하는 복잡한 과정이다. 하나의 작업을 수동으로한 뒤 이를 묶는 작업은 복잡하므로 Iac(Infrastructure as Code)을 도입하여 yml과 같은 파일 형태로 작성한 뒤 이를 활용하여 환경을 구성하는 형식으로 변화하고 있다.
docker-compose.yml -> 컨테이너환경 cloudformation -> aws 에서 서버 인프라 환경 heat -> openstack 에서 서버 인프라 환경 terraform
- 컨테이너의 모든 통신은 shim 을 통해 이루어지게 되고 해당 내용은 shim 에서 containerd 와 통신을 통해 관리된다.
-> shim 은 컨테니어의 입출력, 로그를 d 에게 전달한다.
- 컨테이너는 이미지로부터 배포된다.
- 이미지는 iso 파일과 같이 정적인 파일이다.
- 따라서 추가 작성된 내용은 기본적으로 저장되지 않는다.
- 이를 해결하기 위해서는 별도의 볼륨을 사용해야 한다.
nfs(binding)
- 호스트의 특징 디렉토리와 컨테이너의 특정 디렉토리를 마운트
/root/test:/var/www/htmlisci(volume)
- 별도의 볼륨을 생성하고 해당 볼륨을 컨테이너의 특정 디스크로 활용하는 방법
testvolume:/root /root 는 /dev/sda3 과 같이 특정 파티션이 된다.
tmpfs
- 디스크/스토리지의 특정 공간을 사용하는 것이 아니라 메모리를 사용하는 방법이다. 속도가 빠른 대신 영구 보관은 불가능하다.
- public registry (docker hub 불특정 다수가 접속할 수 있는 공간)
- private registry (틀정 사용자나 그룹 사용자가 접속할 수 있는 공간)
- local registry (도커 데몬이 동작하는 내 컴퓨터)
- docker cotainer ls --all
동작중/중지중인 모든 컨테이너 리스트 확인- docker image ls
로컬 저장소에 있는 이미지들의 리스트 확인- docker container run
생성+시작- docker container stop
중지- docker container rm
삭제(미리 중지되어 있어야한다. 만약 동작중인 상태에서 삭제하고 싶다면 -f 를 붙인다)
- -i = 대화식으로 컨터이너에게 명령 전달 가능
- -t = ssh와 같은 연결 방법을 제공한다.
- dokcer container exec ctnname ls
= 컨테이너에 직접 들어가지 않고 외부(호스트)에서 명령을 전달하고 결과값도 호스트에서 받고 싶다면- -d = 컨테이너를 백그라운드에서 동작 시킨다.
- --restart = --restart=always 데몬 실행과 함께 자동으로 컨테이너가 실행된다. in-failure를 사용하면 처음 컨테이너 시작시 또는 생성시 정상실행이 되지 않거나 정상 생성이 되지 않는 경우 계속해서 실행을 시도할 수 있다.
- -v = 볼륨제공, 비슷한 옵션으로 --mount도 사용가능하다. mount는 과거에는 compose에서만 사용이 가능했으나 17번 이후부터는 container run에서도 사용이 가능하게 되었다.
- -h(--hostname) = 컨테이너 내에서 사용하는 호스트 명
- --name = 관리를 위한 목적으로 컨테이너의 이름을 지정할 수 있다.
- -p = 호스트의 특정포트와 컨테이너의 특정포트를 매핑
- -P = 호스트의 랜덤포트와 컨테이너의 특정포트를 매핑
- --link = 두개 이상의 컨테이너를 연결하는 방법으로 IP가 아닌 이름으로
--link dbctn:mysql
link 옵션은 compose에서는 더이상 사용화지 않는다.
- os 컨테이너 (centos, fedora, ubuntu)
- 애플리케이션 컨테이너 (httpd, node, python)
docker container run -it --name centos1 --hostname test centos:7 /bin/bash
- docker 컨테이너를 생성하고, 실행하는데 명령을 대화형으로 전달하는 옵션을 사용하며, 실행시 /bin/bash 명령을 전달한다.
docker container rm -f $(docker container ls --all -q)
$( ) -> 동작/중지중인 모든 컨테이너들의 id 만을 출력하라
볼륨 삭제
docker volume rm $(docker volume ls -q)
rapa@rapa:~$ docker container run -it --name centos01 -v testvol1:/root centos:7 /bin/bash
[root@eff02c1008f5 /]# df -h | grep /root /dev/sda5 20G 9.3G 8.8G 52% /root
- 위와 같이 호스트에 있는 여유공간을 사용할 수 있다. 만약 볼륨의 크기를 지정하여 사용하고 싶다면 외부 플러그인을 활용해야 한다.
rapa@rapa:~$ docker container ls --all CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES eff02c1008f5 centos:7 "/bin/bash" 4 minutes ago Exited (0) 14 seconds ago centos01
rapa@rapa:~$ docker volume ls DRIVER VOLUME NAME local testvol1
rapa@rapa:~$ docker container rm centos01 centos01
rapa@rapa:~$ docker volume ls DRIVER VOLUME NAME local testvol1
- 컨테이너를 삭제하더라도 볼륨은 여전히 남아있다.
rapa@rapa:~$ docker container run -it --name centos02 -v testvol1:/root centos:7 /bin/bash
- 기존 볼륨을 새로운 컨테이너인 centos02 에 연결하여 생성함.
[root@3635c760270f /]# ls /root/ anaconda-ks.cfg test.txt [root@3635c760270f /]#
- 기존 컨테이너에서 생성했던 파일을 여전히 볼 수 있다.
docker container run -it --name centos03 --label color=blue centos:7 /bin/bash
- 지정한 특정 라벨을 출력
rapa@rapa:~$ docker container inspect centos03 -f "{{.Config.Labels.color}}"- 컨테이너 IP 주소만 출력
rapa@rapa:~$ docker container inspect centos03 -f "{{.NetworkSettings.IPAddress}}" 172.17.0.3
- docker0 는 도커가 설치되면 자동으로 생성되는 네트워크 브릿지이며 NAT 를 통해 컨테이너를 외부와 연결시켜준다.
- 도커 네트워크 리스트
rapa@rapa:~$ docker network ls NETWORK ID NAME DRIVER SCOPE b5bf852a5904 bridge bridge local bridge -> NAT 를 통해 외부와 연결한다. 3ead376f089f host host local host -> 호스트의 주소를 컨테이너와 동일하게 취급한다. 39430d1f4412 none null local none -> 네트워크 사용하지 않음
- swarm 과 같은 클러스터 환경에서는 "overlay" 드라이버가 생성된다. 이는 kvm 과 같은 환경에서 터널을 구성하는 작업이 생략된다.
워드프레스 구축하기
-> 실제환경에서는 php설치, apache설치, mariadb(mysql) 설치, wordpress 소스코드가 필요하다.
하지만 컨테이너를 이용하게 되면 이를 두개의 컨테이너에 구성할 수 있다.
- mysql이미지 - 배포 -> DB 컨테이너
- wordpress 이미지 -> 배포 -> WP 컨테이너
DB 컨테이너 생성
rapa@rapa:~$ docker container run -d --name wpdb -v wpdbvol:/var/lib/mysql --restart=always -e MYSQL_ROOT_PASSWORD=test123 -e MYSQL_DATABASE=wordpress mysql:5.7
- Mysql 은 DB 와 Table 에 대한 정보가 /var/lib/mysql 에 저장된다. 이를 볼륨과 mount 한다.
WP 컨테이너 생성
docker container run -d --restart=always -p 8080:80 --name=wp -e WORDPRESS_DB_PASSWORD=test123 -e WORDPRESS_DB_NAME=wordpress -e WORDPRESS_DB_USER=root --link wpdb:mysql -v wpvol:/var/www/html wordpress
- 포트 지정, DB 연결시 필요한 환경 변수 설정, DB 와 link, 볼륨 마운트
cAdvisor 모니터링 컨테이너 생성
- cAdvisor 는 서비스 운영을 하면서 필요한 시스템 Metric ( CPU / 메모리 사용률 / 네트워크 트래픽 등 ) 을 모니터링 하면서 특이사항이 있을 때, 대응하기 위해 모니터링 수행을 위한 도구
docker run --volume=/:/rootfs:ro --volume=/var/run:/var/run:rw --volume=/sys:/sys:ro --volume=/var/lib/docker/:/var/lib/docker:ro --publish=9559:8080 --detach=true --name=cadvisor google/cadvisor:latest
컨테이너 모두 삭제
docker container rm -f $(docker container ls --all -q)
사용하지 않는 네트워크 삭제
- 활용되지 않는 즉 컨테이너에 적용하지 않은 네트워크 삭제
rapa@rapa:~$ docker network prune
- 활용되지 않는 즉 컨테이너에 적용하지 않은 볼륨 삭제
rapa@rapa:~$ docker volume prune
- 동작중인 컨테이너 이미지로 변환 -> commit
- tar 파일을 이용하여 내용을 이미지로 전송하는 방식으로 새로운 이미지 만들기 -> inmge save
3**** : Dockerfile을 이용하여 이미지 생성하기일종의 명세서를 작성하는 방법FORM centos:7을 업데이트 하고 싶다면
RUN yum -y update RUN yum -y install httpd
RUN
- 명령어 작성, 이미지에 패키지 설치, 업데이트 등의 명령을 실행하고자 하는 경우 작성한다.
[쉘형식] RUN apt -y install nginx SUN yum -y install httpd [exec 형식] RUN ["echo","이것은 테스트입니다."]
CMD, ENTRYPOINT
CMD : 컨테이너로 배포될 때 실핼할 명령어로 추가할 수 있다.
"Cmd": [ "nginx", "-g", "daemon off;" ], "Cmd": [ "httpd-foreground" ],
방법 1. CMD nginx -g 'daemon off;' 2. CMD ["nginx", "-g","daemon off;"]
ENTRYPOINT : 컨테이너로 배포될 때 사용하는 명령어
ENTRYPOINT nginx -g 'daemon off;'
CMD 와 ENTRYPOINT
- 둘다 DOckerfile 내에서 1번만 사용해야한다. (여러번 사용하면 마지막 라인만 처리된다.)
FROM ubuntu ENTRYPOINT ["top"] CMD ["-d","10"]
docker container run -it test:1.0 docker container run -it test:1.0 -d 2
- CMD, ENTRYPOINT에서 실행하는 명령어가 docker container run에서 실행하는 옵션과 동일한 경우 ENTRYPOINT 모두 처리한다. 하지만 CMD는 동일 옵션이 있는 경우 docker container run에 있는 옵션만을 처리한다. ENTRYPOINT는 고정적으로 실행할 명령을 작성하고 CMD는 변경될 가능성이 있느 매개변수, 옵션등에 대하여 지정할때 주로 사용한다.
- 추가적으로 만약 컨테이너로 배포될 때 실행해야할 명령어가 ENTRYPOINT, CMD 두개 가지고는 너무 부족한 경우에는 쉘 파일을 만들고 CMD나 ENTRYPOINT를 이용하여 해당 쉘을 실행하도록 한다.
COPY
- 호스트 환경의 파일, 디렉터리를 이미지 안에 복사하는 경우 작성한다.
COPY index.html /var/www/html
ADD
- "COPY"를 포함한다.
- URL에 있는 파일을 붙여 넣기 하는 것도 가능하다.
- 또한 패키지, 압축 파일의 경우에는 이를 해제하여 내용물만 붙여넣기 할 수 있다. 단, URL 상의 tar 파일등은 해제 되지 않은 상태에서 붙여 넣기 된다.
COPY test.tar /var/www/html -> /var/www/html/test.tar 압축상태 ADD test.tar /var/www/html -> /var/www/html/test 내 압축 해제된 파일
VOLUME
- 이미지에 볼륨을 할당하고자 할 때 사용한다.
VOLUME /var/log VOLUME ["/var/log"]
EXPOSE
- EXPOSE는 마치 방화벽에서 몇번 포트를 열것인가를 지정하는 것
ONBUILD
- ONBUILD는 이를 이용하여 베이스 이미지를 만들때에는 필요하지 않지만 생성된 이미지를 베이스이미지로 활용할 경우에는 사용되는 명령
실습
- 우리는 웹 개발 팀장이다. 팀원중에 /blog를 만드는 팀(blog 팀)에게 다음과 같이 지시했다.
"제가 index.html 파일을 만들테니 blog팀은 개발된 파일, 디렉터리를 blog.tar로 만들어서 빌드하세요."팀장
rapa@rapa:~/0818$ vi Dockerfile FROM centos:7 RUN yum -y install httpd EXPOSE 80 ADD index.html /var/www/html/index.html ONBUILD ADD blog.tar /var/www/html/ CMD httpd -D FOREGROUND
rapa@rapa:~/0818$ touch index.html
rapa@rapa:~/0818$ echo "<h2>yang yang</h2>" > index.html
rapa@rapa:~/0818$ docker build -t webbase:1.0 .
팀원
rapa@rapa:~/0818$ mkdir blogdev rapa@rapa:~/0818$ cd blogdev/ rapa@rapa:~/0818/blogdev$ mkdir blog
rapa@rapa:~/0818/blogdev$ touch blog/blog.html
rapa@rapa:~/0818/blogdev$ echo "<h2>blog team yang </h2>" > blog/blog.html
rapa@rapa:~/0818/blogdev$ tar cf blog.tar blog/*
rapa@rapa:~/0818/blogdev$ ls blog blog.tar
rapa@rapa:~/0818/blogdev$ touch Dockerfile rapa@rapa:~/0818/blogdev$ vi Dockerfile FROM webbase:1.0
rapa@rapa:~/0818/blogdev$ docker build -t webbase:blog .
배포
rapa@rapa:~/0818/blogdev$ docker container run -d -p 8888:80 webbase:blog
- 접속해보기
http://211.183.3.141:8888
-> 팀장
http://211.183.3.141:8888/blog/blog.html
-> 팀원
WORKDIR
- 컨테이너 내에서 작업할 경로 설정
WORKDIR /var/www | | ---------------> 사이에서 일어나는 작업은 /var/www에서 일어난다 | WORKDIR /root
USER
- 작업 사용자 지정하기
ARG
- 컨테이너가 아니라 이미지에서 사용하는 변수 지정
Quiz.
- ubuntu 18.04 이미지를 베이스 이미지로 하여 nginx를 설치하고 해당 nginx에서는 개발자가 작성한 index.html 파일이 보이도록 설정한다.
- 외부에서 접속시 해당 컨테이너의 웹페이지가 보여야 하며 포트번호는 8881을 이용하여 접속할 수 있어야 한다.
- 단, 위의 실습전 각 ubuntu의 ip 주소는 192.168.1.101~126으로 설정해야한다.
웹서비스를 위한 컨테이너의 기본 홈 디렉토리 base image home dir centos/ubuntu /var/www/html httpd /usr/local/apache2/htdocs nginx /usr/share/nginx/html
- VMnet10 번을 VMnet0으로 변경
- IP yaml 파일 변경
rapa@rapa:~/0818/blogdev$ sudo vi /etc/netplan/01-network-manager-all.yaml # Let NetworkManager manage all devices on this system network: ethernets: ens32: addresses: [192.168.1.112/24] gateway4: 192.168.1.1 nameservers: addresses: [8.8.8.8, 168.126.63.1] dhcp4: no version: 2 # renderer: NetworkManager
- 네트워크 적용
rapa@rapa:~/0818/blogdev$ sudo netplan apply
- IP 확인
rapa@rapa:~/0818/blogdev$ ip a
- 도커 이미지 생성
rapa@rapa:~/0818$ vi Dockerfile FROM ubuntu:18.04 RUN apt-get -y update && apt-get -y upgrade RUN apt-get -y install nginx EXPOSE 80 ADD index.html /var/www/html/index.html CMD ["nginx", "-g", "daemon off;"]
rapa@rapa:~/0818$ docker build -t webbase:2.0 .
- 이미지 배포
rapa@rapa:~/0818/blogdev$ docker container run -d -p 8880:80 webbase:blog
Quiz2.
- 다음 조건을 활용하여 배포된 컨테이너는 접속 즉시 설치페이지에서 설치후 게시판을 사용할 수 있어야한다.
이미지
centos:7을 base로 하여 xe:1.0 이미지를 만들어야한다.