Docker
가상화
로컬 / 가상 머신 / 컨테이너
로컬
- 서비스 따라서 호스트 운영체제(서버 운영체제)의 선택에 제한적일 수 있다. 애플리케이션을 배포하는 경우에도 개발 환경과 동일하게 구성되지 않는 경우 오류를 예측하기가 어렵기 때문에 각 배포환경을 최대한 동일하게 구성되도록 신경을 많이 써야한다.
가상화 방식
가상머신(VM)
- VM은 하드웨어, 운영체제 수준에서의 가상화방식이다. 각 가상머신은 운영체제(OS), 바이너리, 라이브러리, 애플리케이션 전체를 포함하고 있다. 가상머신의 실행은 하이퍼바이저(hypervisor)라는 소프트웨어가 필요하며, 이는 호스트 서버의 물리적 하드웨어 리소스를 가상머신에 분배해주는 역할을 수행한다.
- 운영체제를 부팅하고 서비스를 시작하는데 상대적으로 더 많은 시간이 필요하다.
- 각 가상머신에는 운영체제가 포함되어 더 많은 디스크 공간, CPU, 메모리의 자원이 필요해진다.
- 개별 가상머신의 운영체제는 독립된 형태로 별도의 개별 관리가 필요하다.
- 완전한 격리, 강력한 보안, 다양한 운영체제 환경이 필요한 경우 가상머신 방식이 적합.
컨테이너
- 운영체제 수준에서의 가상화방식이다. 각 컨테이너는 자체적으로 필요한 바이너리, 라이브러리, 애플리케이션을 포함하고, 호스트 서버 OS의 커널을 공유하게 된다. 따라서 각 컨테이너에는 독립적인 운영체제가 필요하지 않으며, 이를 통해 리소스 효율성과 성능이 향상된다.
- 컨테이너는 애플리케이션 수준에서의 격리를 수행하기 때문에, 애플리케이션을 직접 실행하는 것과 거의 비슷한 실행속도를 가지며, 이는 가상머신 방식에 비해서 효율이 높다. 또한 성능은 직접 로컬에 구현한 애플리케이션 대비 90% 이상의 성능을 보여준다.
- 컨테이너는 오케스트레이션 툴을 통해서 관리할 수 있다.
- 리소스 효율성, 빠른 사용, 이식성, 확장성이 필요한 경우 컨테이너가 적합.
2023년 12월 28일
Docker 설치
우분투 가상머신 생성
Get Ubuntu Server | Download | Ubuntu
- LTS는 장기 사후지원을 해주는 버전으로 일반적으로 서비스 운영목적으로 운영체제를 선택할 때 사용한다.
- 다른 버전의 경우 사후지원 기간이 6개월, 3개월 단위로 짧은 경우가 있으므로 확인 후 받을 것!
- 메모리 공간은 무조건 4기가 다 줄 필요는 없고, 도커에 구동하는 서비스의 크기에 따라 유동적으로 정해도 상관없다.
- 받아둔 우분투 설치 이미지를 선택한다.
- 이어서 가상머신을 실행한다.
- 첫번째 선택지를 선택해서 우분투 운영체제를 설치한다.
- 언어는 그대로 영어로 진행한다.
- 인스톨러를 업데이트 후 설치를 진행한다.
- 이 부분은 업데이트 없이 바로 설치를 진행해도 상관없다.
- 키보드의 언어도 영어로 유지한다.
- 첫번째 항목은 경우 보편적으로 많이 사용되는 패키지들을 포함한 설치 방식
- 두번째 항목은 최소한의 패키지 구성으로 설치하는 방식
- 현재 가상머신의 기본 네트워크 구성값인 NAT이므로 내부 주소 10.0.2.15가 할당되어 있다.
- 미러사이트를 확인하고 최신 패키지들로 갱신한다.
- 저장소는 특별한 이유가 있는게 아니라면 기본값을 유지한다.
- 마찬가지로 특별한 사유가 있지 않다면 자동으로 설정된 파티셔닝 값으로 진행해도 문제는 없다.
- 다만 구성할 컨테이너가 부하량이 높은 경우는 조금 고민을 더 해보기..
- 자동 설정된 값으로 이어서 진행한다.
- 우분투에서는 관리자 계정 root는 기본적으로 잠궈두고, 대신 사용자를 별도로 생성하도록 하여 생성한 계정을 관리자로 설정하여 사용하게 된다.
- 기술지원을 받을 수 있는 구독을 필요하면 진행하면 된다. (유료임)
- openSSH 서버를 구성하면 외부에서 SSH 프로토콜로 접근하여 원격 작업이 가능하다.
- 외부 원격 접속이 필요없거나, 보안이 중요한 환경인 경우 추전하는 서비스는 아니다.
- 서버 환경에서 보편적으로 많이 사용하는 패키지들을 자동으로 구성하여 설치할 수 있는 메뉴
- 필요한 패키지를 선택해서 설치를 진행할 수 있다.
- 업데이트 후 설치를 완료하면 재시작을 진행한다.
- cdrom 언마운트 실패 시 그냥 엔터를 치면 넘어가진다.
원격 접속 설정
- 현재 ssh 서비스에 대한 접속만 추가해준다.
- 이후 다른 서비스들은 필요할 때 추가해도 상관없음.
- 현재 호스트의 2222와 게스트의 22가 연결되어 있으므로 적절하게 설정값을 채워준다.
- 나머지 설정값들은 취향껏 설정해준다.
Docker 설치
Overview of Docker Desktop | Docker Docs
- 다음 자동 설치 스크립트로 docker를 설치할 수 있다.
- apt 또는 docker desktop으로도 설치 할 수 있음.
itwillbs@dockersrv:~$ sudo wget -qO- https://get.docker.com/ | sh |
[sudo] password for itwillbs: 1234 (안보임)
sudo
- 다음에 오는 작업을 root의 권한을 일시적으로 얻어서 작업을 한다.
- 아무 계정이나 다 사용할 수는 없고 sudoer 그룹에 속한 계정들만 권한을 빌려 사용할 수 있다.
- 관리 계정인 root는 외부에서 공격에 표적이 되기 쉬우므로 일반적으로 잠궈두고 사용하지 않는다. 대신 다른 사용자 계정들을 활용하여 root의 권한을 빌려 작업하는 형태로 사용할 수 있다.
- docker는 기본적으로 root 계정에서 구동되는 서비스로 일반계정이 docker 서비스를 관리하려면 sudo 명령어가 필요하다.
- 현재 접속 중인 계정을 docker 그룹에 추가한다.
itwillbs@dockersrv:~$ sudo adduser $USER docker |
Adding user `itwillbs' to group `docker' ...
Adding user itwillbs to group docker
Done.
- docker ps는 현재 실행 중인 컨테이너 목록을 조회한다.
실행 중인 컨테이너가 없으므로 아무런 내용도 보이지 않음.
itwillbs@dockersrv:~$ sudo docker ps |
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Docker Hub
Explore Docker's Container Image Repository | Docker Hub
mysql - Official Image (docker.com)
sudo docker run --name mysql1228 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=1234 -d mysql:innovation |
itwillbs@dockersrv:~$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
268169114d92 mysql:innovation "docker-entrypoint.s…" 9 seconds ago Up 8 seconds 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql1228
2024년 1월 2일
도커의 주요 용어/개념
도커 엔진(Docker Engine)
- 도커 엔진은 도커 컨테이너를 구축하고 운영하는데 사용되는 핵심 도구
- 도커 엔진은 서버(도커 데몬), API, CLI 클라이언트
- 도커 엔진은 오픈소스로 만들어졌다.
- Docker Desktop는 오픈 소스가 아님!!
이미지(Image)
- 도커 이미지는 애플리케이션을 구성하는 모든 라이브러리, 바이너리, 환경 값들을 모두 모아 패킹해놓은 파일
- 이미지는 불변성을 가지므로, 한 번 생성 후에는 수정은 할 수 없다.
- 변경이 필요한 경우 재생성을 해야한다.
도커 허브(Docker Hub)
- 이미지를 저장하는 저장소들을 레지스트리라고 한다.
- 여러 도커용 레지스트리가 있지만 그 중 가장 유명하고 데이터가 많은 곳은 도커 허브이다.
- 도커에서 직접 운영하며 대부분의 서비스들의 이미지들이 등록되어 있고 배포되고 있다.
컨테이너(Container)
- 컨테이너는 도커 이미지의 실행 인스턴스
- 동일한 이미지를 기반으로하여 여러 컨테이너를 생성할 수 있다.
- 컨테이너를 생성하면 기반 이미지의 내용은 복사가 아닌 참조의 형태로 사용한다.
- 각 컨테이너는 독립적으로 실행되며, 호스트 시스템과 다른 컨테이너와의 격리를 보장한다.
- 컨테이너는 저장 레이어에 수정 된 내용을 저장 할 수 있다.
- 저장 레이어는 볼륨이나 바인드를 해두지 않으면 컨테이너가 삭제될 때 같이 삭제된다.
- 컨테이너는 한번 생성을 하면 설정을 바꿀 수 없다.
외부 저장
볼륨(Volume)
- 컨테이너와 연결되는 호스트의 저장공간
- 컨테이너 내부 데이터는 컨테이너 삭제 시 사라지지만 특정 경로를 볼륨과 연결해둔다면 연결한 경로 내부에 저장되는 데이터들을 실제로는 호스트 공간에 저장되므로 컨테이너가 삭제되더라도 그대로 유지된다.
바인드(Bind)
- 컨테이너 내부의 경로를 호스트의 특정 경로와 연결하는 방법
- 바인드 된 경로의 데이터는 볼륨과 마찬가지로 컨테이너의 삭제 여부와는 상관없이 데이터를 유지한다.
- 바인드의 경우 호스트의 경로이기도 하기 때문에 호스트에서 편집이나 데이터 이동의 작업이 필요한 경우 활용할 수 있다.
- 일반적으로 파일의 수정이 필요한 작업인 경우 컨테이너 내부에서는 새롭게 패키지를 설치하는 방법을 권하지 않기 때문에 외부에서 수정을 해야하는데 외부와 연결하는 방법 중 하나가 바인드이다.
네트워크(Network)
- 컨테이너 간의 통신을 할 수 있는 네트워크를 생성할 수 있다.
- 호스트 방식과 브릿지 방식을 지원한다.
host
- 호스트 네트워크는 컨테이너가 호스트의 IP와 포트를 직접 사용하는 방식이다.
- 호스트 모드의 경우 오버헤드가 적은 편이다.
bridge
- 호스트 내부에 컨테이너들의 네트워크를 별도로 만들어준다.
- 외부와 통신을 하기 위해서는 포트 포워딩, 포트 맵핑과 같은 설정을 적용해야 한다.
- 컨테이너간 격리가 필요한 환경에 적합하다.
2024년 1월 3일
Docker CLI
- 도커 엔진을 명령어로 다루는 방법
docker 이미지 관리
docker search
- 도커 허브에서 필요한 서비스 이미지들을 검색한다.
- docker search 서비스명
Explore Docker's Container Image Repository | Docker Hub
itwillbs@dockersrv:~$ docker search nginx |
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 19425 [OK]
unit Official build of NGINX Unit: Universal Web … 20 [OK]
nginxinc/nginx-unprivileged Unprivileged NGINX Dockerfiles 140
nginx/nginx-ingress NGINX and NGINX Plus Ingress Controllers fo… 87
nginx/nginx-prometheus-exporter NGINX Prometheus Exporter for NGINX and NGIN… 33
nginxinc/nginx-s3-gateway Authenticating and caching gateway based on … 3
nginx/unit This repository is retired, use the Docker o… 64
…
docker pull
- 특정 이미지를 레지스트리에서 내려 받는다.
- 이미지에는 태그가 있는데 보통은 동일 이미지를 다른 구성으로 배포하거나 버전별 배포를 할 때 태그값으로 구분한다.
- 내려 받을 때 태그값을 생략하면 최신버전(latest)이 받아진다.
itwillbs@dockersrv:~$ docker pull nginx |
Using default tag: latest
latest: Pulling from library/nginx
af107e978371: Pull complete
336ba1f05c3e: Pull complete
8c37d2ff6efa: Pull complete
51d6357098de: Pull complete
782f1ecce57d: Pull complete
5e99d351b073: Pull complete
7b73345df136: Pull complete
Digest: sha256:2bdc49f2f8ae8d8dc50ed00f2ee56d00385c6f8bc8a8b320d0a294d9e3b49026
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
docker images
- 현재 호스트에 저장된 도커 이미지 목록
itwillbs@dockersrv:~$ docker images |
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql innovation 73246731c4b0 2 weeks ago 619MB
nginx latest d453dd892d93 2 months ago 187MB
docker rmi
- 이미지를 삭제하는 명령어
- 컨테이너에서 참조 중인 이미지는 바로 삭제는 불가능하다.
- 참조 중인 이미지를 삭제하려면 강제 삭제 옵션을 사용 또는 참조하는 컨테이너를 삭제 후 이미지를 삭제
- docker rmi 이미지명[:태그명]
itwillbs@dockersrv:~$ docker rmi nginx |
Untagged: nginx:latest
Untagged: nginx@sha256:2bdc49f2f8ae8d8dc50ed00f2ee56d00385c6f8bc8a8b320d0a294d9 e3b49026
Deleted: sha256:d453dd892d9357f3559b967478ae9cbc417b52de66b53142f6c16c8a275486b9
Deleted: sha256:efa10324a701d6accf82a523dcaba9aadf21943e214a8879d10c13284bffcd5f
Deleted: sha256:4178f7184379d32ddc77d881dca384ac307dedb0c42f521fe633c5a95f308cd6
Deleted: sha256:454122e697d0fd11338a4e00fd1d20acd2eaf133544321160606c908ca395911
Deleted: sha256:b4ad020cdacfccfc4faf3dcd7984f600391d3972063112dd2b37dfbd30105993
Deleted: sha256:6f226612ab7aafdd91fcc90917ad3d7a667237a78785fe2309faf160559a69a7
Deleted: sha256:9671ab29815f09e9c2552b872e0097732d4b5efb5dfdc91630853d7bf7221f1a
Deleted: sha256:7292cf786aa89399bca4e3edd105d3b2ee0683a46ef1f5ff436c0f9d1d49e765
docker 컨테이너 관리
docker run
- docker run <options> <image-name>
- 컨테이너를 새롭게 생성하거나 또는 정지된 컨테이너를 실행해주는 명령어
- 컨테이너의 포트는 무조건 호스트와 연결할 필요는 없으며, 포트 공개를 하지 않더라도 동일 브릿지 네트워크에 포함된 컨테이너들 간에는 통신을 할 수 있다.
- 기존 로컬에 받아진 이미지들이 있는 경우 허브에서 pull하지 않고 바로 생성하지만, 필요한 이미지가 없는 경우 자동으로 이미지를 받아서 컨테이너를 생성하게 된다.
주요 옵션
- 전체 옵션은 https://docs.docker.com/engine/reference/run/ 여기 링크를 참고
- -d : 실행하는 컨테이너를 터미널과 분리하여 백그라운드에서 실행시킨다.
- -p : 호스트와 컨테이너의 포트를 연결한다.
ex) -p 8888:8080 → 호스트포트:게스트포트 호스트의 8888 포트를 컨테이너의 8080으로 연결한다. - -e : 컨테이너에 전달할 환경변수값을 지정
- -v : 볼륨, 바인드 연결 경로를 설정하는 옵션
- --name : 생성되는 컨테이너의 이름을 설정하는 옵션. 생략하게 되면 자동으로 만들어진 랜덤이름이 부여
- 현재 docker 호스트가 가상머신 상태에서 돌아가는 상황이므로 포트 포워딩이 2단계에 거쳐서 진행된다.
- 아래의 명령어를 실행하면 (가상머신) 8888 - 8080 (컨테이너) 가 연결된 상태로 서비스가 시작된다.
itwillbs@dockersrv:~$ docker run --name my-tomcat -d -p 8888:8080 tomcat |
Unable to find image 'tomcat:latest' locally
latest: Pulling from library/tomcat
3dd181f9be59: Pull complete
0f838805bddf: Pull complete
e39426fdaf82: Pull complete
646f6a954707: Pull complete
7ad7501a603a: Pull complete
9a85227543ee: Pull complete
9f254810c153: Pull complete
2e60b97b5a62: Pull complete
Digest: sha256:1107d758acf1bef7748969e0f84c1d071490c1da46a97ab2c04e5cd12f4e4a2b
Status: Downloaded newer image for tomcat:latest
1dfff500e1b6223edb0f180b11fd545e68cfa69e0c7b49c6d6bb3acf895a30e1
- 가상머신과 도커 호스트 간에도 포트 포워딩을 걸어준다.
- (호스트) 8888 <-> 가상머신(도커 호스트) 8888 <-> 컨테이너 8080
- 결과적으로 호스트 컴퓨터의 8888번 포트로 진입하면 최종적으로 컨테이너의 8080에 연결된다.
- 현재 컨테이너 내부에는 배포중인 애플리케이션이 없기 때문에 에러 페이지가 뜬다.
- 도커 이미지로 배포되는 톰캣의 경우 경량화를 위해서 기본으로 들어가는 설정페이지도 제거되어 있음.
docker ps
- docker ps
- 컨테이너 목록을 출력한다. 기본값으로는 실행 중인 컨테이너만 보여준다.
- -a : 정지되어 있는 컨테이너를 포함하여 모두 출력.
itwillbs@dockersrv:~$ docker ps -a |
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1dfff500e1b6 tomcat "catalina.sh run" 27 minutes ago Up 27 minutes 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp my-tomcat
268169114d92 mysql:innovation "docker-entrypoint.s…" 5 days ago Exited (0) 5 days ago mysql1228
docker stop
- docker stop <container-id/name>
- 실행 중인 컨테이너를 종료한다.
itwillbs@dockersrv:~$ docker stop my-tomcat |
my-tomcat
- my-tomcat은 종료되었으므로 ps 명령어로도 조회되지 않는다.
itwillbs@dockersrv:~$ docker ps |
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
docker start
- docker start <container-id/name>
- 정지된 컨테이너를 실행한다.
itwillbs@dockersrv:~$ docker start mysql1228 |
mysql1228
itwillbs@dockersrv:~$ docker ps |
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
268169114d92 mysql:innovation "docker-entrypoint.s…" 6 days ago Up 8 seconds 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql1228
docker restart
- docker restart <container-id/name>
- 실행 중인 컨테이너를 재시작한다.
itwillbs@dockersrv:~$ docker restart mysql1228 |
mysql1228
docker rm
- docker rm <container-id/name>
- 동작 중인 컨테이너는 바로 삭제가 불가능하다.
- 옵션 -f : 실행 중인 컨테이너를 강제로 삭제한다.
itwillbs@dockersrv:~$ docker rm mysql1228 |
Error response from daemon: You cannot remove a running container 268169114d92aee803db59b9e46b748f2ad61b986c52c985b21283ecf7033dee. Stop the container before attempting removal or force remove
itwillbs@dockersrv:~$ docker stop mysql1228 |
mysql1228
itwillbs@dockersrv:~$ docker rm mysql1228 |
mysql1228
docker logs
- docker logs <container-id/name>
- 컨테이너의 내부 로그 기록을 조회한다.
- 여기서 보여지는 로그 값은 서버의 터미널 상에 출력되는 실행 내역이다.
itwillbs@dockersrv:~$ docker run --name mysql1228 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=1234 -d mysql:innovation |
68be9ee351ba8a76f3b08886abc9b0846f79743c11f7f92056e10b5271a0d0c8
itwillbs@dockersrv:~$ docker logs mysql1228 |
2024-01-03 06:26:41+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.2.0-1.el8 started.
2024-01-03 06:26:41+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2024-01-03 06:26:41+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.2.0-1.el8 started.
2024-01-03 06:26:42+00:00 [Note] [Entrypoint]: Initializing database files
2024-01-03T06:26:42.013170Z 0 [System] [MY-015017] [Server] MySQL Server Initialization - start.
2024-01-03T06:26:42.014315Z 0 [Warning] [MY-011068] [Server] The syntax '--skip-host-cache' is deprecated and will be removed in a future release. Please use SET GLOBAL host_cache_size=0 instead.
2024-01-03T06:26:42.014417Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.2.0) initializing of server in progress as process 79
2024-01-03T06:26:42.020909Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2024-01-03T06:26:42.907040Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
…
docker exec
- docker exec -it <container-id/name> <command>
- 컨테이너 내부에 명령을 전달하는 명령어
- -it 옵션 : 컨테이너와 상호작용할 수 있는 터미널로 연결한다.
- 주의할 점은 내부 수정이 필요없거나 경량화를 많이해서 배포하는 이미지인 경우 쉘 자체를 제거한채로 배포하는 경우도 있을 수 있다. 이런 경우에는 내부에서 뭘 작업하기 보다는 바인드를 통해서 외부와 컨테이너 내부의 경로를 연결하여 컨테이너 외부 호스트 환경에서 편집작업을 수행하면 된다.
- 바인드 / 볼륨을 연결하는 방법은 이후에서 다룰 예정
itwillbs@dockersrv:~$ docker exec -it mysql1228 bash |
bash-4.4#
2024년 1월 7일
portainer
- 도커의 컨테이너, 이미지, 볼륨과 같은 설정값들을 관리할 수 있는 오픈소스 기반의 도구
https://hub.docker.com/r/portainer/portainer-ce
docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest |
- -d : 명령어 실행 시 컨테이너와 현재 작업 중인 터미널은 분리하여 백그라운드에서 컨테이너를 동작시킨다.
- -p 8000:8000 -p 9443:9443 : 호스트의 8000과 9443 포트를 컨테이너의 8000, 9443과 연결시킨다.
- --name portainer : 생성되는 컨테이너의 이름을 portainer라 설정한다. 컨테이너 명은 중복될 수 없다.
- --restart = always : 컨테이너에 대한 재시작 정책을 설정한다.
- -v /var/run/docker.sock:/var/run/docker.sock : 호스트의 /var/run/docker.sock의 경로를 컨테이너의 /var/run/docker.sock와 바인드한다. docker.sock 도커의 관리를 할 수 있는 중요 파일이다.
- -v portainer_data:/data : portainer_data는 볼륨명으로 생성된 볼륨과 컨테이너의 경로를 연결한다.
- portainer/portainer-ce:latest : 컨테이너 생성에 사용되는 이미지와 태그를 작성
portainer 연결하기
- 컨테이너 생성 후 일정 시간안에 서비스에 접속해야지 설정작업을 진행할 수 있다.
- 만약, 시간을 넘긴 경우 컨테이너를 재생성해서 진행한다.
- 왼쪽은 로컬 환경을 관리하는 목적인 경우
- 오른쪽은 원격 환경을 관리하는 목적인 경우
- 도커의 많은 부분의 설정들을 관리할 수 있다.
DockerFile
- 이미지 생성 작업 명령어들로 새로운 이미지를 만들 수 있는 명령어 파일.
- 명령어를 통해서 배포에 필요한 작업이나 리소스들을 배치할 수 있다.
- 각 명령어들은 하나의 레이어로 저장되기 때문에 가능하다면 적은 명령어로 구성해주는 것이 경량화에 도움을 준다.
FROM
- 이미지를 구축하기 위한 베이스 이미지를 설정한다.
FROM ubuntu:20.04 |
RUN
- 이미지를 빌드하는 동안 명령을 실행한다. 주로 패키지 설치하는 목적으로 사용한다.
- && 는 터미널에서 명령어들을 연결해서 실행 할 때 사용하는 기호이다.
RUN apt-get update && apt-get install -y curl |
WORKDIR
- 특정 경로에서 작업을 하거나 명령어를 입력해야 하는 경우 경로를 이동할 때 사용한다.
- 이동한 경로가 없는 경우 생성도 해준다.
WORKDIR /app |
COPY
- 호스트 시스템의 파일이나 디렉토리를 이미지로 복사하는 명령어
- 경로는 상대경로 절대경로 다 사용가능하다.
- 호스트의 현재 경로 아래의 myapp을 컨테이너의 /app에 복사한다.
COPY ./myapp /app |
ADD
- 호스트가 아닌 외부 경로(웹, …)의 파일들을 추가할 때 사용한다.
ADD https://example.itwillbs.com/aaaa.war /usr/src/things |
2024년 1월 9일
CMD
- 작성 중인 이미지를 참조하여 컨테이너가 만들어지고 실행될 때 수행될 기본 명령어를 작성
- 사용자가 이미지를 참조하여 생성하는 경우 CMD 명령어를 통해서 베이스 이미지의 CMD 명령어를 대체하는 것도 가능하다.
- 따라서 CMD 에 등록된 명령어는 기본값일 뿐 무조건 실행되는 명령어는 아님.
- 터미널의 명령어를 아래와 같이 공백 기준으로 리스트로 분리해서 작성한다.
CMD ["node", "app.js"] |
ENTRYPOINT
- 컨테이너가 시작 될 때 실행되는 명령어. CMD는 기본값의 역할만 하기 때문에 다른 값이 입력되면 실행되지 않지만, ENTRYPOINT는 기본값이 아닌 실제 실행되어야 하는 명령이므로 덮어씌우기 어렵다.
ENTRYPOINT ["node", "app.js"] |
EXPOSE
- 컨테이너가 열어둬야 하는 포트를 지정한다. 외부와 통신을 해야하는 서비스를 만드는 경우 필요한 포트를 설정해둔다.
- 컨테이너 생성 시 EXPOSE된 모든 포트를 다 열어두는 것이 아닌 필요한 포트만 열 수 있다. 강제성이 없음.
EXPOSE 8080 |
ENV
- 컨테이너 생성 시 사용될 환경 변수값을 작성한다.
- 공개적으로 배포되는 이미지의 경우 사용자의 설정이 필요한 환경 값들을 미리 입력한 상태로 배포할 수 없기 때문에 컨테이너 실행 시 환경변수를 통해서 설정을 입력 받아 컨테이너를 만들 수 있다.
ENV MYSQL_ROOT_PASSWORD |
VOLUME
- 이미지를 활용해서 컨테이너를 생성할 때 호스트와 연결되어야 할 경로를 지정
- 컨테이너 생성 시 주요한 호스트와 연결해야 할 경로를 작성한다. 다만, 호스트와 연결하지 않는다고 에러가 발생하거나 하지는 않는다. 연결하지 않게되면 컨테이너 삭제 시 데이터가 유지되지 않는다.
VOLUME ["/data"] |
USER
- 일반적으로 리눅스 기반의 서비스 이미지인 경우 root계정을 관리에 사용을 하지만 별도의 관리 계정이 해당 계정으로 작업하도록 지정할 수 있다.
USER myuser |
ARG
- 이미지 빌드할 때 사용하는 변수를 정의하는 명령어
ARG VERSION=latest |
Docker image 빌드 예제
- 애플리케이션을 빌드해서 이미지를 배포하는 경우 원하는 경로를 생성하고 리소스들을 적절하게 배치해준다.
- Funweb 경로를 생성하고 내부에 새로운 dockerfile을 생성한다.
itwillbs@dockersrv:~$ mkdir Funweb itwillbs@dockersrv:~$ cd Funweb/ itwillbs@dockersrv:~/Funweb$ nano dockerfile |
FROM tomcat:9-jdk11
COPY ./Funweb.war /usr/local/tomcat/webapps/
EXPOSE 8080
CMD ["catalina.sh", "run"]
- dockerfile에 필요한 이미지를 생성하는 명령어를 적절하게 작성한 후 저장해준다.
docker build
- docker build 명령어는 dockerfile의 명령어를 기반으로 이미지를 만들어주는 명령어이다.
- docker build [옵션] dockerfile경로
- -t옵션 : 생성하는 이미지의 이름을 명시해준다. 해당 옵션을 생략하면 dockerfile 디렉토리명을 활용하여 이름을 작성해준다.
- docker hub에 업로드하려는 경우 이미지명은 계정명/이미지명:태그 형태로 작성해준다.
- 이미지를 빌드하는 경우 기본적으로 도커 호스트의 로컬에 이미지가 만들어지며 로컬에만 존재하는 이미지의 경우에도 컨테이너 생성에 사용이 가능하다.
- 태그명은 동일한 애플리케이션의 이미지를 빌드할 때 최신 버전, 구성에 따라서 이미지들을 구분하기 위한 값이다. 생략하는 경우 기본적으로 latest 가 지정된다.
- 아래의 명령어에서는 -t 옵션으로 생성할 이미지명을 fun-tomcat으로 지정했으며, 터미널의 접속 위치와 동일한 경로에 dockerfile이 존재하는 경우 dockerfile의 위치를 현재 위치를 가리키는 .으로 표시할 수 있다.
itwillbs@dockersrv:~/Funweb$ docker build -t fun-tomcat . itwillbs@dockersrv:~/Funweb$ docker images |
REPOSITORY TAG IMAGE ID CREATED SIZE
fun-tomcat latest 2d8ef292f748 About a minute ago 416MB
mysql innovation 73246731c4b0 3 weeks ago 619MB
tomcat 9.0 aec1892be4c2 3 weeks ago 455MB
tomcat latest f42b2599b503 3 weeks ago 454MB
portainer/portainer-ce latest 1a0fb356ea35 4 weeks ago 294MB
- 생성된 fun-tomcat 이미지로 컨테이너를 생성한다.
- 현재 실습하는 환경에 따라서 포트포워딩과 같은 설정을 적절하게 적용시켜준다.
- 실습 시 포트포워딩 구성은 아래의 설정을 적용하는 경우
호스트pc 9999 <-> 도커호스트(가상머신) 9999 <-> 컨테이너 8080 의 형태로 연결된다. - 가상머신 환경이 아닌 경우 컨테이너 생성 시 적용하는 -p 옵션만 있어도 호스트 외부와 연결이 가능하다.
itwillbs@dockersrv:~/Funweb$ docker run --name funtom -d -p 9999:8080 fun-tomcat |
2024년 1월 10일
Docker compose
- 컨테이너를 생성하는 설정값들을 적용하여 배포할 수 있는 수단.
- json의 형식을 사용하는 yaml, yml파일을 사용하여 작성할 수 있다.
- 단일 컨테이너도 docker compose로 구성할 수 있으며, 여러 컨테이너들을 한번에 배포하는 것도 가능하다.
- docker compose로 구성되는 컨테이너들은 단일 애플리케이션으로 취급하며, 한번에 애플리케이션 단위로 컨테이너들을 배포하거나 관리하는 것도 가능하다. 개별 컨테이너를 docker run으로 따로 구성하는 것보다 docker compose가 선언적으로 관리하는 부분에서 더 편리하다.
- 필요한 경우 애플리케이션 내부 네트워크를 구성해서 외부의 간섭없이 내부 컨테이너들만 서로 통신을 할 수 있도록 구성할 수 있다.
- 여러 서비스들이 들어가는 애플리케이션 배포 시 하나의 이미지에 여러 서비스들을 넣을 경우 컨테이너의 특장점인 경량성을 잃기 쉽게 때문에 여러 컨테이너들로 개별로 구성하여 배포하는 것이 유리하다.
- 기본적으로 코드로 작성되기 때문에 git과 같은 형상관리 도구들로 관리하는 것도 가능하며, 자동화 도구로 자동으로 애플리케이션을 빌드하고 docker compose로 배포하는 것도 가능하다.
- 모놀리식방식의 애플리케이션의 경우 docker compose에 모든 서비스들을 다 작성해야하고, 마이크로 서비스 방식의 경우에는 기능별 개별동작할 수 있는 구성으로 docker compose를 작성해준다.
- docker-compose가 설치되어 있지 않다면 패키지를 설치해준다.
sudo apt install docker-compose |
- 아래에 명시된 구성의 두개의 컨테이너를 docker-compose로 한번에 묶어서 배포하는 것을 진행한다.
docker run --name mysql1228 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=1234 -d mysql:innovation docker run --name funtom -d -p 9999:8080 fun-tomcat |
- 먼저 애플리케이션 리소스가 들어갈 디렉토리를 생성해준다.
itwillbs@dockersrv:~$ mkdir mywebapp |
itwillbs@dockersrv:~$ cd mywebapp/ |
- docker-compose.yml파일을 생성한다.
- tomcat과 mysql의 컨테이너들은 애플리케이션의 서비스 단위로 작성된다.
itwillbs@dockersrv:~/mywebapp$ nano docker-compose.yml |
version: '3.8'
services:
mysql:
image: mysql:innovation
container_name: mysql-8.2
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: "1234"
networks:
- mynetwork
tomcat:
image: fun-tomcat
container_name: funtomapp
ports:
- "9999:8080"
networks:
- mynetwork
networks:
mynetwork:
driver: bridge
- 컨트롤 + S, 컨트롤 + X로 저장 후 종료한다.
- docker-compose.yml은 형식은 다르지만 기본적으로 docker run 명령어의 구성과 동일하다.
- 들여쓰기에 주의하여 각 항목에 맞게 내용을 작성해준다.
- 상세한 docker-compose의 작성 명세는 다음의 링크를 참고한다.
- https://docs.docker.com/compose/compose-file/
itwillbs@dockersrv:~/mywebapp$ docker-compose up -d |
Creating network "mywebapp_mynetwork" with driver "bridge"
Creating funtomapp ... done
Creating mysql-8.2 ... done
itwillbs@dockersrv:~/mywebapp$ docker ps |
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3f2c1a512cc6 mysql:innovation "docker-entrypoint.s…" 24 seconds ago Up 23 seconds 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql-8.2
a3ee4ccf20aa fun-tomcat "catalina.sh run" 24 seconds ago Up 23 seconds 0.0.0.0:9999->8080/tcp, :::9999->8080/tcp funtomapp
f92e541ab447 portainer/portainer-ce:latest "/portainer" 47 hours ago Up 18 minutes 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp, 0.0.0.0:9443->9443/tcp, :::9443->9443/tcp, 9000/tcp portainer
- 두 컨테이너가 정상적으로 잘 생성 된 것을 확인할 수 있다.
Docker hub 업로드
- 직접 레지스트리를 구성하여 애플리케이션을 배포할 수도 있지만, 공개되는 애플리케이션을 배포하는 경우 docker hub와 같은 온라인 레지스트리에 업로드하여 배포할 수도 있다.
- docker hub는 pull로 이미지를 받을 때는 익명으로 로그인 없이 100개의 이미지까지 하루에 받을 수 있으나 그 이상인 경우 계정이 필요하며, 공개가 아닌 private으로 비공개 배포를 하는 경우 유료 플랜을 사용해야 한다.
- 애플리케이션을 배포하는데는 계정을 요구한다.
- 배포 시 이미지명은 계정명/이미지명[:태그] 의 형태로 빌드되어야 한다.
docker tag
- docker 이미지의 이름을 처음 이미지를 빌드할 때 지정할 수 있으나 나중에 다른 이름이 필요할 수 있다. 이때 docker tag를 사용하면 기존의 이미지에 추가적인 이름을 더 달아줄 수 있다.
- 기존의 이미지를 복사하는 형태가 아닌 기존 이미지를 가리키는 이름하나가 더 생기는 형태이다.
itwillbs@dockersrv:~/mywebapp$ docker images |
REPOSITORY TAG IMAGE ID CREATED SIZE
fun-tomcat latest 2d8ef292f748 23 hours ago 416MB
mysql innovation 73246731c4b0 3 weeks ago 619MB
tomcat 9.0 aec1892be4c2 3 weeks ago 455MB
tomcat latest f42b2599b503 3 weeks ago 454MB
portainer/portainer-ce latest 1a0fb356ea35 4 weeks ago 294MB
- docker tag 이전 이미지명 새로운 이미지명
- fun-tomcat:funweb을 가리키는 새로운 이름 doveis99/fun-tomcat:funweb 를 추가하였음.
itwillbs@dockersrv:~/mywebapp$ docker tag fun-tomcat:funweb doveis99/fun-tomcat:funweb |
itwillbs@dockersrv:~/mywebapp$ docker images |
REPOSITORY TAG IMAGE ID CREATED SIZE
doveis99/fun-tomcat funweb 2d8ef292f748 24 hours ago 416MB
fun-tomcat funweb 2d8ef292f748 24 hours ago 416MB
fun-tomcat latest 2d8ef292f748 24 hours ago 416MB
mysql innovation 73246731c4b0 3 weeks ago 619MB
tomcat 9.0 aec1892be4c2 3 weeks ago 455MB
tomcat latest f42b2599b503 3 weeks ago 454MB
portainer/portainer-ce latest 1a0fb356ea35 4 weeks ago 294MB
docker login
- docker에서 콘솔 명령어로 작업을 할 때 계정의 자격증명을 등록하는 명령어.
itwillbs@dockersrv:~/mywebapp$ docker login |
Log in with your Docker ID or email address to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com/ to create one.
You can log in with your password or a Personal Access Token (PAT). Using a limited-scope PAT grants better security and is required for organizations using SSO. Learn more at https://docs.docker.com/go/access-tokens/
Username: doveis99
Password: 계정 패스워드 (안보임)
WARNING! Your password will be stored unencrypted in /home/itwillbs/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
docker push
- 로컬의 이미지를 온라인에 배포한다.
- 이미지의 이름에 업로드 계정명이 있어야 한다.
itwillbs@dockersrv:~/mywebapp$ docker push doveis99/fun-tomcat:funweb |
The push refers to repository [docker.io/doveis99/fun-tomcat]
af896e45af25: Pushed
37999ae2e0f1: Mounted from library/tomcat
700814480069: Mounted from library/tomcat
5d9281485da0: Mounted from library/tomcat
7a2648dbf8bc: Mounted from library/tomcat
6dd56ceb442b: Mounted from library/tomcat
21f256208a91: Mounted from library/tomcat
8f51a32da2de: Mounted from library/tomcat
a1360aae5271: Mounted from library/tomcat
funweb: digest: sha256:cf094257de6069bee0934c1c3578aaf84a9096fdef4470d3b869acee0842c2e4 size: 2206
doveis99/fun-tomcat - Docker Image | Docker Hub
docker logout
- docker hub 관련 작업이 끝나서 자격증명이 더 필요없는 경우 로그아웃한다.
itwillbs@dockersrv:~/mywebapp$ docker logout |
Removing login credentials for https://index.docker.io/v1/
[아이티윌부산] 핀테크 개발자 과정(2023-04) 2차 팀프로젝트 발표 - 1팀 (youtube.com)
------------------------------
DML(Data Manipulation Language / 데이터조작어)
- 데이터를 다루는 종류의 문법 분류
INSERT (데이터 입력)
- 새로운 데이터를 테이블에 입력할 때 사용하는 문법
- INSERT INTO : 새로운 데이터를 추가할 테이블, 컬럼의 목록 작성하는 절
- VALUES : 입력 될 데이터의 목록이 작성되는 절
- 새로운 데이터 입력 시 입력할 테이블의 데이터타입과 데이터 입력값들을 미리 확인해준다.
DESC departments; |
Field |Type |Null|Key|Default|Extra|
---------------+------------+----+---+-------+-----+
department_id |int unsigned|NO |PRI| | |
department_name|varchar(30) |NO | | | |
manager_id |int unsigned|YES |MUL| | |
location_id |int unsigned|YES |MUL| | |
- 컬럼의 목록을 작성한 경우 VALUES절에는 컬럼 목록의 순서와 컬럼의 데이터타입을 맞춰 입력값을 작성해준다.
INSERT INTO departments (department_id, department_name, manager_id, location_id) VALUES (280, 'Storm', 100, 1700); |
- 테이블의 데이터 끝에 새롭게 추가된 데이터가 조회된다.
SELECT * FROM departments; |
department_id|department_name |manager_id|location_id|
-------------+--------------------+----------+-----------+
10|Administration | 200| 1700|
20|Marketing | 201| 1800|
…
260|Recruiting | | 1700|
270|Payroll | | 1700|
280|Storm | 100| 1700|
- 모든 컬럼이 아닌 일부 컬럼에만 값 입력
- 이때도 컬럼의 목록에 맞는 순서와 값을 values절에 작성해준다.
INSERT INTO departments (department_id, department_name) VALUES (290, 'HOME'); |
- 입력 컬럼목록에 없던 컬럼들은 입력값을 받지 못해 NULL의 데이터가 입력된 것을 볼 수 있다.
SELECT * FROM departments; |
department_id|department_name |manager_id|location_id|
-------------+--------------------+----------+-----------+
10|Administration | 200| 1700|
20|Marketing | 201| 1800|
…
270|Payroll | | 1700|
280|Storm | 100| 1700|
290|HOME | | | ← NULL
- 컬럼 목록을 생략한 경우 테이블의 모든 컬럼에 대한 입력값을 기본 순서대로 values절에 작성해야한다.
INSERT INTO departments VALUES (300, 'Coffe', 100, 1700); |
SELECT * FROM departments; |
department_id|department_name |manager_id|location_id|
-------------+--------------------+----------+-----------+
10|Administration | 200| 1700|
20|Marketing | 201| 1800|
…
290|HOME | | |
300|Coffe | 100| 1700|
UPDATE (데이터 갱신)
- 기존 데이터의 값을 새로운 값으로 갱신할 때 사용하는 문법
- UPDATE절 : 갱신할 데이터가 있는 테이블명 작성
- SET절 : 갱신 작업의 내용을 작성한다. 컬럼 = 값 의 구조로 `=` 기호는 할당의 의미로 사용된다. 한번에 여러 컬럼의 값을 갱신할 수도 있다.
- WHERE절 : 갱신 작업의 대상이 될 행을 선택하는 조건식을 작성한다. where절은 생략가능하나, 생략하는 경우 테이블의 모든 행이 갱신의 대상이 된다.
SELECT employee_id, salary FROM employees ORDER BY employee_id; |
employee_id|salary |
-----------+--------+
100|24000.00|
101|17000.00|
102|17000.00|
…
- employees 테이블에서 100번 사원에 대해 salary 컬럼의 값을 100만큼 더한 값으로 갱신
UPDATE employees SET salary = salary + 100 WHERE employee_id = 100; |
employee_id|salary |
-----------+--------+
100|24100.00|
101|17000.00|
102|17000.00|
…
SELECT employee_id, salary FROM employees ORDER BY employee_id; |
employee_id|salary |
-----------+--------+
100|24100.00|
101|17000.00|
102|17000.00|
103| 9000.00|
…
- WHERE절을 생략하는 경우 테이블의 모든 행에 대해 SET절의 작업이 적용된다. (주의!!)
UPDATE employees SET salary = salary * 1.1; |
employee_id|salary |
-----------+--------+
100|26510.00|
101|18700.00|
102|18700.00|
103| 9900.00|
…
DELETE (데이터 삭제)
- 기존 테이블의 데이터를 삭제할 때 사용하는 구문
- DELETE절 : 삭제할 데이터가 있는 테이블명 작성
- WHERE절 : 삭제할 행에 대한 조건식 작성
실습 테이블 생성 구문
CREATE TABLE copy_emp AS (SELECT * FROM employees); |
SELECT * FROM copy_emp; |
employee_id|first_name |last_name |email |
-----------+-----------+-----------+--------+ …
100|Steven |King |SKING |
101|Neena |Kochhar |NKOCHHAR|
102|Lex |De Haan |LDEHAAN |
103|Alexander |Hunold |AHUNOLD |
…
- 사원번호 100의 사원의 행을 삭제
DELETE FROM copy_emp WHERE employee_id = 100; |
employee_id|first_name |last_name |
-----------+-----------+-----------+
...
101|Neena |Kochhar |
102|Lex |De Haan |
103|Alexander |Hunold |
…
- 조건절 없이 데이터 삭제 시 테이블의 모든 데이터가 삭제된다.
DELETE FROM copy_emp; |
SELECT * FROM copy_emp; |
employee_id|first_name|last_name|email|phone_number|hire_date|job_id|salary|commission_pct|manager_id|department_id|
-----------+----------+---------+-----+------------+---------+------+------+--------------+----------+-------------+
DDL(Data Definition Language / 데이터정의어)
- 데이터베이스를 구성하는 오브젝트의 구조를 다루는 문법 종류
- CREATE : 새로운 오브젝트를 정의하는 문법
- ALTER : 기존 오브젝트의 구조를 변형하는 문법
- DROP : 기존 오브젝트의 구조를 삭제하는 문법
데이터베이스의 오브젝트 종류
테이블 | 데이터베이스의 데이터 저장의 기본 단위. 행으로 구성되어 있다. |
뷰 | 테이블의 논리적인 부분 집합의 구조. 가상의 테이블의 오브젝트 |
인덱스 | 일부 쿼리의 성능을 올려주는 오브젝트 |
테이블(CREATE TABLE)
- 데이터를 저장하는데 필요한 속성, 형식, 제약등을 정의하는 문법
문법
CREATE TABLE 테이블명 ( 컬럼명1 데이터타입(크기) [컬럼레벨 제약조건] [, 컬럼명2 데이터타입(크기), ...] [테이블레벨 제약조건] ); |
실습 데이터베이스 생성
CREATE DATABASE test; |
- 생성 후 데이터베이스 목록에서 새로고침 후 선택
- test1 테이블 생성
CREATE TABLE test1 ( NUM INT, NAME VARCHAR(30), SALARY INT, BIRTHDATE DATE ); |
DESC test1; |
Field |Type |Null|Key|Default|Extra|
---------+-----------+----+---+-------+-----+
NUM |int |YES | | | |
NAME |varchar(30)|YES | | | |
SALARY |int |YES | | | |
BIRTHDATE|date |YES | | | |
- 모든 컬럼을 출력할 때는 테이블의 기본 컬럼 순서로 결과가 출력된다.
SELECT * FROM test1; |
NUM|NAME|SALARY|BIRTHDATE|
---+----+------+---------+
INSERT INTO test1 (NUM, NAME, SALARY, BIRTHDATE) VALUES (1, 'Burger', 100, '2023-08-09'); |
SELECT * FROM test1; |
NUM|NAME |SALARY|BIRTHDATE |
---+------+------+----------+
1|Burger| 100|2023-08-09|
Q. test2 테이블을 생성
- 테이블명 : orders컬럼 구성
컬럼명 | 데이터타입 | 크기 |
order_id | int | |
customer_id | int | |
product_id | int | |
quantity | int | |
price | DECIMAL | (10,2) |
order_date | DATE |
CREATE TABLE test2( order_id INT, customer_id INT, product_id INT, quantity INT, price DECIMAL(10, 2), order_date DATE ); |
DESC test2; |
Field |Type |Null|Key|Default|Extra|
-----------+-------------+----+---+-------+-----+
order_id |int |YES | | | |
customer_id|int |YES | | | |
product_id |int |YES | | | |
quantity |int |YES | | | |
price |decimal(10,2)|YES | | | |
order_date |date |YES | | | |
옵션 DEFAULT 값
- 데이터 입력 시 특정 컬럼의 값을 입력하지 않은 경우 NULL값 대신 입력 될 기본 값을 설정하는 옵션
- DEFAULT 값 설정 시 설정이 적용될 컬럼과 동일한 데이터타입의 리터럴값 또는 함수를 작성해준다.
- hire_date 컬럼에는 옵션으로 기본값을 NOW() 함수의 결과를 설정하였음.
CREATE TABLE testdefault ( emp_id INT, hire_date DATETIME DEFAULT NOW() ); |
DESC testdefault; |
Field |Type |Null|Key|Default |Extra |
---------+--------+----+---+-----------------+-----------------+
emp_id |int |YES | | | |
hire_date|datetime|YES | |CURRENT_TIMESTAMP|DEFAULT_GENERATED|
- CURRENT_TIMESTAMP은 NOW() 함수와 동일한 기능을 하는 함수이다.
- hire_date 컬럼에 대한 입력값을 생략했으나 hire_date 컬럼에 적용된 default 값이 동작하여 NOW()함수의 결과가 대신 입력된 것을 볼 수 있다.
INSERT INTO testdefault (emp_id) VALUES (1); |
SELECT * FROM testdefault;
emp_id|hire_date |
------+-------------------+
1|2023-08-22 15:36:46|
- hire_date 컬럼에 대해서 명시적으로 NULL값을 입력하게 되면 DEFAULT 설정이 동작하지 않는다.
INSERT INTO testdefault (emp_id, hire_date) VALUES (2, NULL); |
SELECT * FROM testdefault; |
emp_id|hire_date |
------+-------------------+
1|2023-08-22 15:36:46|
2| |
제약조건(CONSTRAINT)
- 데이터의 무결성 유지를 위해 테이블에 적용되는 데이터에 대한 제약 설정
NOT NULL - NULL 값을 허용하지 않음
- 해당 제약조건이 적용된 컬럼에 NULL값을 허용하지 않는 제약
- 값의 입력이 필수인 컬럼에 설정
- NOT NULL 제약조건의 작성 위치는 제약조건이 적용 될 컬럼의 기본 정의 이후에 작성을 한다.
CREATE TABLE testnn ( name VARCHAR(30) NOT NULL, age INT ); |
DESC testnn; |
Field|Type |Null|Key|Default|Extra|
-----+-----------+----+---+-------+-----+
name |varchar(30)|NO | | | | ← NULL값을 허용하지 않음
age |int |YES | | | |
암시적 NULL 데이터 입력
- name 컬럼에 대한 입력값을 작성하지 않은 상태에서 컬럼에 기본적으로 null값 대신 입력 될 기본값(DEFAULT) 설정도 존재하지 않는 경우 NULL에 대한 대체값이 없게되므로 에러가 발생한다.
INSERT INTO testnn (age) VALUES (10); |
SQL Error [1364] [HY000]: Field 'name' doesn't have a default value
명시적 NULL 데이터 입력
- name 컬럼에 명시적으로 NULL값을 입력하려는 경우 DEFAULT 설정도 적용되지 않기 때문에 NULL값을 피할 수단이 없으므로 NOT NULL제약조건에 의해서 입력이 바로 차단되어 버린다.
INSERT INTO testnn (name, age) VALUES (NULL, 10); |
SQL Error [1048] [23000]: Column 'name' cannot be null
UNIQUE - 고유한 값만 입력
- UNIQUE 제약조건이 적용된 컬럼에는 중복값을 입력할 수 없도록 제약이 걸리게 된다.
- NULL 값은 비교 불가능 데이터이므로 UNIQUE로도 중복값으로 걸러 낼 수 없다.
CREATE TABLE testuk ( id INT UNIQUE ); |
INSERT INTO testuk VALUES (1); |
SELECT * FROM testuk; |
id|
--+
1|
INSERT INTO testuk VALUES (NULL); |
SELECT * FROM testuk; |
id|
--+
|
|
|
|
|
|
|
|
1|
2|
3|
PRIMARY KEY - 테이블의 대표 컬럼 지정
- NOT NULL + UNIQUE 의 기능을 가진다.
- 테이블의 행 데이터들을 개개별로 구분 할 수 있는 의미의 컬럼에 적용하는 제약조건이다.
- 테이블 당 한번만 사용가능하다.
CREATE TABLE testpk ( id INT PRIMARY KEY, ci_id INT NOT NULL UNIQUE, name varchar(10) ); |
DESC testpk; |
Field|Type |Null|Key|Default|Extra|
-----+-----------+----+---+-------+-----+
id |int |NO |PRI| | |
ci_id|int |NO |UNI| | |
name |varchar(10)|YES | | | |
DROP TABLE (테이블 삭제)
- 기존 테이블의 구조를 삭제하는 문법
- 테이블을 삭제하면 테이블의 모든 데이터도 함께 삭제된다.
문법
DROP TABLE 테이블명; |
SHOW tables; |
Tables_in_test|
--------------+
test1 |
test2 |
- 테이블 중 test2 테이블을 삭제한다.
DROP TABLE test2; |
Tables_in_test|
--------------+
test1 |
DESC test2; |
SQL Error [1146] [42S02]: Table 'test.test2' doesn't exist
SELECT * FROM test2; |
SQL Error [1146] [42S02]: Table 'test.test2' doesn't exist
-------------------------