1. 도커 데몬 설정
(1) 도커 데몬 제어 : -H
-H 옵션은 도커 데몬의 API를 사용할 수 있는 방법을 추가합니다.
아무런 설정을 하지 않고 도커 데몬을 실행하면 /usr/bin/docker를 위한 소켓인 /var/run/docker.sock을 사용합니다.
그리하여 단순히 dockerd를 입력해 도커 데몬을 실행해도 도커 클라이언트의 CLI를 사용할 수 있습니다.
dockerd
dockerd -H unix:///var/run/docker.sock
위 두 명령에는 차이가 없습니다.
어차피 기본적으로 사용되는 유닉스 소켓을 지정한것이고 별도로 지정하지 않아도 해당 소켓을 사용하기 때문입니다.
dockerd -H tcp://0.0.0.0:2375
위는 Remote API만을 위한 바인딩 주소만 입력을 했고 소켓은 지정하지 않았습니다.
소켓은 비활성화 되므로 도커 클라이언트(docker 명령어)를 사용할 수 없습니다.
따라서 도커 클라이언트를 위한 소켓과 Remote API를 위한 바인딩 주소를 동시에 설정합니다.
dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375
위는 호스트의 모든 NIC에 할당된 IP주소와 2375번 포트로 도커 데몬을 제어하고 도커 클라이언트도 사용 가능합니다.
(2) 도커 데몬에 보안 적용 : --tlsverify [이 부분은 진행중 에러발생으로 추후 다시 정리]
도커를 설치하면 기본적으로 보안 연결이 설정돼 있지 않습니다.
실제 운영환경에서 도커를 사용할 때 보안을 적용하지 않는 것은 바람직하지 않습니다.
보안이 미적용된 환경에서 Remote API를 위해 바인딩된 IP주소와 포트 번호만 알면 도커를 제어할 수 있기 때문입니다.
보안을 적용할 때 사용될 파일은 다음과 같습니다.
- ca.pem
- server-cert.pem
- server-key.pem
- cert.pem
- key.pem
클라이언트 측에서 도커 데몬에 접근하려면 다음과 같은 파일이 필요합니다.
- ca.pem
- cert.pem
- key.pem
■ 서버 측 파일 생성
[root@localhost ~]# mkdir keys && cd keys
1) 인증서에서 사용될 키를 생성합니다.
[root@localhost keys]# openssl genrsa -aes256 -out ca-key.pem 4096
Generating RSA private key, 4096 bit long modulus
.................................................++
................................................................++
e is 65537 (0x10001)
Enter pass phrase for ca-key.pem: 비밀번호
Verifying - Enter pass phrase for ca-key.pem: 비밀번호
2) 공용 키(public key)를 생성합니다. (입력하는 모든 항목은 공백으로 둬도 상관없음)
[root@localhost keys]# openssl req -new -x509 -days 10000 -key ca-key.pem -sha256 -out ca.pem
Enter pass phrase for ca-key.pem:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:
3) 서버 측에서 사용될 키를 생성합니다.
[root@localhost keys]# openssl genrsa -out server-key.pem 4096
Generating RSA private key, 4096 bit long modulus
.............................................................................................++
........................................................................................................++
e is 65537 (0x10001)
4) 서버 측에서 사용될 인증서를 위한 인증 요청서 파일을 생성합니다.
(/CN= 다음 부분은 사용중인 도커 호스트의 IP 혹은 도메인 이름을 입력하며, 외부에서 접근가능한 IP주소여야 합니다.)
[root@localhost keys]# openssl req -subj "/CN=192.168.1.166" -sha256 -new -key server-key.pem -out server.csr
5) 접속에 사용될 IP주소를 extfile.cnf 파일로 저장합니다. (IP: 다음 부분은 위와 마찬가지로 IP나 도메인 입력)
[root@localhost keys]# echo subjectAltName = IP:192.168.1.166,IP:127.0.0.1 > extfile.cnf
6) 서버 측의 인증서 파일을 생성합니다.
[root@localhost keys]# openssl x509 -req -days 465 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf
Signature ok
subject=/CN=192.168.1.166
Getting CA Private Key
Enter pass phrase for ca-key.pem:
위 예에서는 192.168.1.166으로 접속하는 연결에 사용되는 인증서 파일이 생성됐습니다.
■ 클라이언트 측 파일 생성
1) 클라이언트 측의 키 파일과 인증 요청 파일을 생성하고, extfile.cnf 파일에 extendedKeyUsage 항목을 추가합니다.
[root@localhost keys]# openssl genrsa -out key.pem 4096
[root@localhost keys]# openssl req -subj '/CN=client' -new -key key.pem -out client.csr
[root@localhost keys]# echo extendedKeyUsage = clientAuth > extfile.cnf
2) 클라이언트 측의 인증서를 생성합니다.
[root@localhost keys]# openssl x509 -req -days 30000 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf
Signature ok
subject=/CN=client
Getting CA Private Key
Enter pass phrase for ca-key.pem:
3) 생성된 파일의 쓰기 권한을 삭제해 읽기 전용 파일로 만듭니다.
[root@localhost keys]# chmod -v 0400 ca-key.pem key.pem server-* ca.pem cert.pem
mode of `ca-key.pem' changed from 0644 (rw-r--r--) to 0400 (r--------)
mode of `key.pem' changed from 0644 (rw-r--r--) to 0400 (r--------)
mode of `server-cert.pem' changed from 0644 (rw-r--r--) to 0400 (r--------)
mode of `server-key.pem' changed from 0644 (rw-r--r--) to 0400 (r--------)
mode of `ca.pem' changed from 0644 (rw-r--r--) to 0400 (r--------)
mode of `cert.pem' changed from 0644 (rw-r--r--) to 0400 (r--------)
4) ~/.docker로 도커 데몬측에서 필요한 파일을 옮깁니다. 필수적이지는 않지만 관리의 편의성 때문입니다.
[root@localhost keys]# cp {ca,server-*,cert,key}.pem ../.docker/
5) 보안 적용을 위한 파일을 모두 생성했으므로 다음 명령어로 암호화가 적용된 도커 데몬을 실행합니다.
TLS 보안적용을 활성화하기 위해 --tlsverify 옵션을 추가하고, --tlscacert, --tlscert, --tlskey 각 파일의 위치를 입력합니다.
[root@localhost keys]# dockerd --tlsverify --tlscacert=/root/.docker/ca.pem --tlscert=/root/.docker/server-cert.pem --tlskey=/root/.docker/server-key.pem -H=0.0.0.0:2376 -H unix:///var/run/docker.sock
그 다음 192.168.1.150 이라는 다른 서버에 docker 설치 후 다음과 같이 접속해보려는데 에러가 발생했습니다.
[root@localhost keys]# docker -H 192.168.1.166:2376 version
Client: Docker Engine - Community
Version: 20.10.7
API version: 1.41
Go version: go1.13.15
Git commit: f0df350
Built: Wed Jun 2 11:58:10 2021
OS/Arch: linux/amd64
Context: default
Experimental: true
Error response from daemon: Client sent an HTTP request to an HTTPS server.
에러 발생으로 추후 다시 정리예정입니다..
(3) 도커 스토리지 드라이버 변경 : --storage-driver
도커는 특정 스토리지 백엔드 기술을 사용해 도커 컨테이너와 이미지를 저장하고 관리합니다.
일부 OS에서는 도커 설치 시 기본적으로 사용하도록 설정된 스토리지 드라이버가 있습니다.
우분투 같은 데비안계열은 overlay2를, 구버전의 CentOS는 devicemapper를 사용하는 것이 대표적입니다.
[root@localhost ~]# docker info | grep -i storage
Storage Driver: overlay2
도커를 사용하는 환경에 따라 스토리지 드라이버는 자동으로 정해지지만 데몬실행 시 변경가능합니다.
--storage-driver를 사용해 선택할 수 있으며 OverlayFS, AUFS, Btrfs, Devicemapper, VFS, ZFS 등이 있습니다.
하나만 선택할 수 있으며 적용된 스토리지 드라이버에 따라 컨테이너와 이미지가 별도로 생성됩니다.
만약 도커가 AUFS를 사용하도록 설정된 OS에서 다음과 같이 도커데몬을 실행하면 별도의 Devicemapper 컨테이너와 이미지를 사용하므로 AUFS에서 사용했던 이미지와 컨테이너는 사용할 수 없습니다.
별도 생서된 Devicemapper 파일은 /var/lib/docker/devicemapper 에 저장되며 AUFS 또한 /var/lib/docker/aufs 디렉토리에 저장됩니다.
dockerd --storage-driver=devicemapper
스토리지 드라이버마다 각각 장단점이 있어 무조건 좋은 스토리지 드라이버라는 것은 없습니다.
각 드라이버의 장단점을 감안해 선택하는 것이 바람직합니다.
dockerd --data-root /DATA/docker
도커데몬이 사용하는 컨테이너와 이미지가 저장되는 디렉토리를 별도로 지정하지 않았다면 드라이버별로 사용되는 컨테이너와 이미지는 /var/lib/docker/드라이버이름 에 저장됩니다.
위와 같이 설정하면 컨테이너와 이미지파일의 저장경로를 지정할 수 있으며, 이는 도커 엔진이 초기화된 상태로 실행됩니다.
위 같이 경로를 지정하여 사용 시 한 디렉토리 내에 여러 드라이버의 파일들이 존재할 경우 strorage-driver 옵션으로 사용할 드라이버를 명시하지 않으면 어느 드라이버를 사용할지 못찾는 상황이 발생해 도커데몬이 시작되지 않습니다.
■ AUFS 드라이버 사용하기
AUFS는 우분투에서 도커를 사용할 때 자동으로 설정되는 드라이버이며 도커에서 오랜기간 사용돼왔고 많은 커뮤니티에서 지원을 받고 있기 때문에 안정성 측면에서 우수하다고 평가받습니다.
그러나 AUFS 모듈은 기본적으로 커널에 포함돼 있지 않으므로 일부 OS에서는 사용이 불가합니다.(RHEL, CentOS)
DOCKER_OPTS="--storage-driver=aufs"
위와 같이 설정해 사용할 수 있으며
[root@localhost ~]# grep aufs /proc/filesystems
[root@localhost ~]# cat /proc/filesystems
nodev sysfs
nodev rootfs
nodev ramfs
nodev bdev
nodev proc
nodev cgroup
nodev cpuset
nodev tmpfs
nodev devtmpfs
nodev debugfs
nodev securityfs
nodev sockfs
nodev dax
nodev bpf
nodev pipefs
nodev configfs
nodev devpts
nodev hugetlbfs
nodev autofs
nodev pstore
nodev mqueue
nodev selinuxfs
xfs
nodev overlay
nodev binfmt_misc
해당 파일을 통해 aufs 를 지원하는지 확인 가능합니다.(위 결과는 CentOS라 지원X)
AUFS는 컨테이너의 실행, 삭제 등의 컨테이너 관련 수행 작업이 매우 빠르므로 PaaS에 적합한 드라이버로 꼽힙니다.
도커에서 지원하는 대표적인 스토리지 드라이버이기 때문에 일반적으로 많이 사용하는 드라이버 중 하나입니다.
■ Devicemapper 드라이버 사용하기
Devicemapper 드라이버는 레드햇 계열의 리눅스 배포판을 위해 개발된 스토리지 드라이버입니다.
CentOS를 포함한 대부분의 리눅스 배포판에서 보편적으로 사용할 수 있다는 장점이 있지만, 성능상의 이유 등으로 인해 더 이상 사용하지 않는 것이 권장되는 deprecated(비추천)된 스토리지 드라이버입니다.
따라서 호스트 커널버전이 너무 낮거나 여러 스토리지 드라이버를 사용할 수 없는 것이 아니라면 overlay 또는 overlay2 스토리지 드라이버를 사용하는 것이 좋습니다.
도커 1.13.0 버전 기준으로 이후에는 OverlayFS를 기본적으로 사용하도록 설정돼 있습니다.
DOCKER_OPTS="--storage-driver=devicemapper"
[root@localhost docker]# dockerd --storage-driver=devicemapper
[root@localhost devicemapper]# ls -ahl /var/lib/docker/devicemapper/devicemapper
합계 12M
drwx------. 2 root root 34 6월 7 13:37 .
drwx------. 4 root root 42 6월 7 13:37 ..
-rw-------. 1 root root 100G 6월 7 13:37 data
-rw-------. 1 root root 2.0G 6월 7 13:37 metadata
devicemapper 드라이버를 사용하도록 설정한 뒤 위 디렉토리를 보면 2개의 파일이 확인됩니다.
100GB의 data라는 파일은 실제로 사용되고 있는건 아니며, 여기에서 공간을 할당받아 이미지와 레이어에 저장합니다.
이것은 이미지와 컨테이너의 데이터가 분리된 디렉토리로 저장되는 것이 아닌 data 파일로 이뤄진 풀에서 블록 단위로 할당받는 구조입니다.
컨테이너와 이미지블록의 정보는 metadata 파일에 저장됩니다.
[root@localhost devicemapper]# ls -sahl /var/lib/docker/devicemapper/devicemapper
합계 12M
0 drwx------. 2 root root 34 6월 7 13:37 .
0 drwx------. 4 root root 42 6월 7 13:37 ..
11M -rw-------. 1 root root 100G 6월 7 13:37 data
596K -rw-------. 1 root root 2.0G 6월 7 13:37 metadata
s 옵션을 줘서 실제 도커 데몬이 차지하는 파일의 크기를 확인할 수 있습니다.
■ OverlayFS 사용하기
레드햇 계열의 OS 등에서 도커 설치 시 자동으로 설정되는 드라이버입니다.
AUFS와 비슷한 원리로 동작하지만 좀 더 간단한 구조로 사용되며성능 또한 조금 더 좋습니다.
따라서 AUFS를 대체할 수 있는 차세대 파일시스템으로 떠오르고 있습니다.
OverlayFS 드라이버는 overlay와 overlay2 드라이버로 나뉩니다.
overlay2는 overlay에 비해 성능이 좀 더 우수하며, 이미지를 구성하기 위해 여러 개의 레이어 구조를 지원합니다.
따라서 가능하다면 overlay2 스토리지 드라이버를 사용하는 것이 권장됩니다.
overlay는 다른 스토리지 드라이버와는 달리 계층화된 이미지 구조를 사용하지 않으며, lowerdir이라는 단일화된 이미지레이어를 사용합니다.
[root@localhost ]# uname -r
3.10.0-1160.24.1.el7.x86_64
[root@localhost ]# grep overlay /proc/filesystems
nodev overlay
[root@localhost docker]# dockerd --storage-driver=overlay
[root@localhost ]# docker run -ti --name test1 ubuntu:18.04
root@411c44772159:/# echo test >> overlayfile
[root@localhost overlay]# ll
합계 0
drwx-----x. 3 root root 18 6월 7 14:50 651b7c540698d434df5a0ccc482228814491ce30b462077623c34a4c5ca630c8
drwx-----x. 3 root root 18 6월 7 14:50 8d6651aeaf16558c1fcf05648bef56ea06d1f2b60e207e2888b85c3f7d5e60ca
drwx-----x. 3 root root 18 6월 7 14:50 c893e7c971a873e0f5351f199707c45b91c5eed25798b9257e28c52c0980660f
drwx-----x. 5 root root 61 6월 7 14:50 f78945e6f449d4549ee4a076effb390680cee580df6d7e2590107fc79dd4e15b
drwx-----x. 4 root root 47 6월 7 14:50 f78945e6f449d4549ee4a076effb390680cee580df6d7e2590107fc79dd4e15b-init
overlay 드라이버를 사용하도록 설정하면 도커 엔진이 초기하되므로 새로운 이미지를 내려받은 뒤 컨테이너가 생성되었습니다. 생성된 컨테인어ㅔ서는 적당한 파일을 새로 생성해 이미지로부터 변경사항을 만듭니다.
호스트로 빠져나온 후 /var/lib/docker/overlay 디렉토리를 보면 위와 같습니다.
이름끝에 -init이 붙은 디렉토리가 방금 생성한 컨테이너를 의미합니다.
-init을 제외한 디렉토리가 실제 컨테이너의 파일시스템을 담고있는 디렉토리입니다.
[root@localhost overlay]# ll f78945e6f449d4549ee4a076effb390680cee580df6d7e2590107fc79dd4e15b
합계 4
-rw-------. 1 root root 64 6월 7 14:50 lower-id
drwxr-xr-x. 1 root root 65 6월 7 14:51 merged
drwxr-xr-x. 4 root root 65 6월 7 14:51 upper
drwx------. 3 root root 18 6월 7 14:50 work
overlay 드라이버는 컨테이너를 사용하기위해 merged, upperdir, lowerdir의 구조로 나눕니다.
lowerdir - 도커이미지 레이어
upperdir - 컨테이너 레이어
upperdir에는 컨테이너에서 발생한 변경 사항을 담고있으며, 위에서 생성한 컨테이너는 overlayfile이라는 변경사항을 가지고 있기 때문에 upperdir 디렉토리에는 overlayfile 파일이 존재합니다.
[root@localhost upper]# ll /var/lib/docker/overlay/f78945e6f449d4549ee4a076effb390680cee580df6d7e2590107fc79dd4e15b/upper
합계 4
drwxr-xr-x. 4 root root 43 6월 7 14:50 dev
drwxr-xr-x. 2 root root 66 6월 7 14:50 etc
-rw-r--r--. 1 root root 5 6월 7 14:51 overlayfile
그리고 upperdir은 이미지 레이어에 해당하는 lowerdir과 함께 마운트되어 최종적으로 컨테이너 내부에 보여주게 되고, 이것이 컨테이너 마운트 지점인 merged 디렉토리입니다.
[root@localhost merged]# ll /var/lib/docker/overlay/f78945e6f449d4549ee4a076effb390680cee580df6d7e2590107fc79dd4e15b/merged
합계 12
drwxr-xr-x. 2 root root 4096 5월 13 08:09 bin
drwxr-xr-x. 2 root root 6 4월 24 2018 boot
drwxr-xr-x. 1 root root 43 6월 7 14:50 dev
drwxr-xr-x. 1 root root 66 6월 7 14:50 etc
drwxr-xr-x. 2 root root 6 4월 24 2018 home
drwxr-xr-x. 8 root root 96 5월 23 2017 lib
drwxr-xr-x. 2 root root 34 5월 13 08:08 lib64
drwxr-xr-x. 2 root root 6 5월 13 08:05 media
drwxr-xr-x. 2 root root 6 5월 13 08:05 mnt
drwxr-xr-x. 2 root root 6 5월 13 08:05 opt
-rw-r--r--. 1 root root 5 6월 7 14:51 overlayfile
drwxr-xr-x. 2 root root 6 4월 24 2018 proc
drwx------. 2 root root 37 5월 13 08:09 root
drwxr-xr-x. 5 root root 58 5월 20 04:44 run
drwxr-xr-x. 2 root root 4096 5월 20 04:44 sbin
drwxr-xr-x. 2 root root 6 5월 13 08:05 srv
drwxr-xr-x. 2 root root 6 4월 24 2018 sys
drwxrwxrwt. 2 root root 6 5월 13 08:09 tmp
drwxr-xr-x. 10 root root 105 5월 13 08:05 usr
drwxr-xr-x. 11 root root 139 5월 13 08:09 var
AUFS와 유사하게 overlay는 이미지에 존재하는 파일에 쓰기 작업을 수행할 때 파일을 컨테이너 레이어인 upperdir로 복사해 사용합니다. 따라서 크기가 큰 파일에 쓰기작업을 수행할 때는 upperdir에 복사하는 시간으로 인해 작업 수행에 지연이 생길 수 있으나, AUFS와는 다르게 계층화된 다중 레이어 구조가 아니기 때문에 복사할 파일을 찾는 과정에서는 AUFS보다 빠릅니다.
■ Btrfs 사용하기
Btrfs는 리눅스 파일시스템 중 하나로 SSD최적화, 데이터압축 등 다양한 기능을 제공합니다.
Devicemapper, Overlay, AUFS와는 다르게 파일시스템을 별도로 구성하지 않으면 도커에서 사용할 수 없습니다.
또한 /var/lib/docker 디렉토리가 btrfs 파일시스템을 사용하는 공간에 마운트돼 있어야만 도커는 btrfs를 스토리지 드라이버로 인식합니다.Btrfs는 리눅스 커널에 포함돼 있으므로 대부분의 리눅스 배포판에서 사용 가능합니다.
service docker stop
yum install btrfs-progs
mkfs.btrfs -f /dev/xvdb
도커 데몬이 실행중이라면 먼저 이를 정지한 뒤 진행합니다.
Btrfs를 생성하기 위한 도구를 설치합니다.
그 다음 Btrfs 스토리지 풀을 생성합니다. (디바이스에 맞게 설정 xvda/xvdb/xvdc 등)
#vi /etc/fstab
/dev/xvdb /var/lib/docker btrfs defaults 0 0
시스템 재부팅 시 Btrfs 디바이스가 마운트되도록 설정
mount -a
fstaqb 파일에 설정한 내용을 적용하기 위해 mount -a 명령 입력
이후 도커 시작 후 스토리지 드라이버 확인
service docker start
docker info | grep Storage
Storage Driver: btrfs
Btrfs는 자체적으로 SSD에 최적화돼 있으며 대체적으로 우수한 성능을 보여줍니다.
또한 리눅스의 파일시스템이 제공하지 않는 여러 기능을 제공한다는 장점도 있습니다.
■ ZFS 드라이버 사용하기
Btrfs처럼 압축, 레플리카, 데이터 중복제거 등 다양한 기능을 제공합니다.
그러나 라이센스 문제로 리눅스 커널에 기본적으로 탑재돼 있지않아 별도의 설치과정이 필요합니다.
# service docker stop
# apt install zfsutils-linux
# modprobe zfs
# zpool create -f zpool-docker /dev/xvdb
# zfs create -o mountpoint=/var/lib/docker zpool-docker/docker
# zfs list -t all
# service docker start
# docker info | grep Driver
먼저 도커데몬이 실행중이면 정지합니다.
zfs 설치 후 modprobe zfs로 모듈을 로드합니다.
그 다음 새로운 zpool을 생성합니다. 해당 zpool의 이름은 zpool-docker로 생성됩니다. (xvdb 디바이스에 맞게)
zfs create로 zfs파일시스템을 생성하고 이를 /var/lib/docker에 마운트합니다.
zfs list로 출력결과를 조회하여 정상적으로 마운트 되었는지 확인합니다.
도커를 재시작한 뒤 docker info 명령어로 스토리지 드라이버가 zfs인지 확인합니다.
ZFS는 메모리를 상당히 소모하는 파일시스템이기 때문에 ZFS를 스토리지 드라이버로 사용하는 도커에서 많은 수의 컨테이너를 동시에 사용해야 한다면 호스트의 자원 사용량을 수시로 확인하는 것이 좋습니다.
'docker' 카테고리의 다른 글
도커 컨테이너 다루기(13) - 도커 데몬 모니터링 (0) | 2021.06.09 |
---|---|
도커 컨테이너 다루기(12) - 도커데몬[3] (0) | 2021.06.08 |
도커 컨테이너 다루기(10) - 도커데몬[1] (0) | 2021.06.05 |
도커 컨테이너 다루기(9) - Dockerfile로 빌드할 때 주의할 점 (0) | 2021.06.04 |
도커 컨테이너 다루기(8) - 도커파일(Dockerfile)[2] (1) | 2021.06.03 |