M1 Docker with lima
lima란
lima는 자동파일공유와 포트 포워딩(WSL2과 유사)을 지원하는 linux vm과 컨테이너를 제공한다.
lima는 일종의 비공식적인 "맥을 위한 컨테이너"라 보면 된다.
✅ 자동 파일 공유 ✅ 자동 포트 포워딩 ✅ 컨테이너 기능 탑재
lima 설치 방법
homebrew를 이용한 설치
brew install limadocker와 docker-compose가 깔려있지 않다면 같이 설치한다
brew install lima docker docker-composehomebrew 없이 설치를 하려 한다면... 수동 설치 매뉴얼
lima가 제대로 설치 됐는지 확인
limactl\
lima에 docker 설치 방법 및 명령어 종류
docker + lima config 파일
해당 프로필 스펙은 다음과 같다
OS: Ubuntu 21.10 (Impish Indri)
CPU: 4 cores
Memory: 4 GiB
Disk: 100 GiB
Mounts: ~ (read-only), /tmp/lima (writable)
SSH: 127.0.0.1:60022
docker가 추가된 docker.yaml 환경설정 파일
# Example to use Docker instead of containerd & nerdctl
# $ limactl start ./docker.yaml
# $ limactl shell docker docker run -it -v $HOME:$HOME --rm alpine
# To run `docker` on the host (assumes docker-cli is installed):
# $ export DOCKER_HOST=$(limactl list docker --format 'unix://{{.Dir}}/sock/docker.sock')
# $ docker ...
# This example requires Lima v0.8.0 or later
images:
# Hint: run `limactl prune` to invalidate the "current" cache
- location: "https://cloud-images.ubuntu.com/impish/current/impish-server-cloudimg-amd64.img"
arch: "x86_64"
- location: "https://cloud-images.ubuntu.com/impish/current/impish-server-cloudimg-arm64.img"
arch: "aarch64"
mounts:
- location: "~"
- location: "/tmp/lima"
writable: true
# containerd is managed by Docker, not by Lima, so the values are set to false here.
containerd:
system: false
user: false
provision:
- mode: system
# This script defines the host.docker.internal hostname when hostResolver is disabled.
# It is also needed for lima 0.8.2 and earlier, which does not support hostResolver.hosts.
# Names defined in /etc/hosts inside the VM are not resolved inside containers when
# using the hostResolver; use hostResolver.hosts instead (requires lima 0.8.3 or later).
script: |
#!/bin/sh
sed -i 's/host.lima.internal.*/host.lima.internal host.docker.internal/' /etc/hosts
- mode: system
script: |
#!/bin/bash
set -eux -o pipefail
command -v docker >/dev/null 2>&1 && exit 0
export DEBIAN_FRONTEND=noninteractive
curl -fsSL https://get.docker.com | sh
# NOTE: you may remove the lines below, if you prefer to use rootful docker, not rootless
systemctl disable --now docker
apt-get install -y uidmap dbus-user-session
- mode: user
script: |
#!/bin/bash
set -eux -o pipefail
systemctl --user start dbus
dockerd-rootless-setuptool.sh install
docker context use rootless
probes:
- script: |
#!/bin/bash
set -eux -o pipefail
if ! timeout 30s bash -c "until command -v docker >/dev/null 2>&1; do sleep 3; done"; then
echo >&2 "docker is not installed yet"
exit 1
fi
if ! timeout 30s bash -c "until pgrep rootlesskit; do sleep 3; done"; then
echo >&2 "rootlesskit (used by rootless docker) is not running"
exit 1
fi
hint: See "/var/log/cloud-init-output.log". in the guest
hostResolver:
# hostResolver.hosts requires lima 0.8.3 or later. Names defined here will also
# resolve inside containers, and not just inside the VM itself.
hosts:
host.docker.internal: host.lima.internal
portForwards:
- guestSocket: "/run/user/{{.UID}}/docker.sock"
hostSocket: "{{.Dir}}/sock/docker.sock"
message: |
To run `docker` on the host (assumes docker-cli is installed), run the following commands:
------
docker context create lima --docker "host=unix://{{.Dir}}/sock/docker.sock"
docker context use lima
docker run hello-world
------다른 예시 파일들은 여기서 확인할수 있다 : lima/examples
docker.yaml을 이용한 설치
docker를 이용하기 위해 docker.yaml 파일을 이용하여 lima를 실행시킨다. 해당 yaml 파일이 있는 곳으로 이동한 다음에 파일을 실행시킨다.
(첨부파일의 docker.yaml 파일을 다운받으면 된다.)
limactl start docker.yaml설치가 완료되기까지 5분 정도의 시간이 걸린다.\
실행중인 리스트 확인하기
limactl list설치한 docker vm 이 잘 떠있는 것을 볼 수 있다.
NAME STATUS SSH ARCH CPUS MEMORY DISK DIR
docker Running 127.0.0.1:51363 aarch64 4 4GiB 100GiB /Users/taejun/.lima/docker\
lima 접속 및 docker 실행 명령어
다음 명령어를 입력하여 lima vm으로 접속한다
limactl shell docker(이후에 나오는 명령어들은 해당 lima vm 에 접속하여 진행하는 단계들이다)
접속후 아래의 명령어를 입력하여 docker 가 잘 실행되는지 확인한다.
docker간단한 docker 명령어
docker-compose up [OPTIONS]
서비스를 위한 컨테이너를 빌드, (재)생성, 시작 및 연결 docker-compose.yml 파일의 위치에서 실행 가능
docker images [OPTIONS] [REPOSITORY[:TAG]]
이미지 조회
docker-compose down
컨테이너 중지, up에서 생성한 컨테이너, 네트워크, 볼륨 및 이미지 제거
docker rm [OPTIONS] CONTAINER [CONTAINER...]
하나 이상의 컨테이너 제거
docker rmi [OPTIONS] IMAGE [IMAGE...]
호스트 노드에서 하나 이상의 이미지를 제거(및 태그 해제)
docker volume prune [OPTIONS]
사용하지 않는 모든 로컬 볼륨 제거
docker exec -it [컨테이너명 or 컨테이너ID] bash
실행 중인 컨테이너에 접속
\
lima에서 docker-compose 사용하기
docker-compose.yml 란?
연결된 다수의 컨테이너를 하나로 통합하여 관리하는 도구
docker-compose 에서는 컨테이너 실행에 사용되는 옵션과 컨테이너 간 의존성을 모두 docker-compose.yml 파일에 적어두고, docker-compose 명령어를 사용하여 컨테이너를 실행 및 관리한다.
docker-compose에 대한 자세한 내용이 궁금하다면 : Docker Compose와 버전별 특징 \
lima에서 docker-compose 설치하기
docker-compose를 사용하기 위해서는 lima vm환경에 설치하여야 한다. 다음의 명령어를 입력한다.
sudo apt install docker-compose설치 후 아래의 명령어를 입력하여 docker-compose가 제대로 설치되었는지 확인한다.
docker-compose제대로 설치되었으면 아래와 같은 화면이 뜬다.
\
docker-compose.yml 항목
docker-compose파일은 다음과 같은 항목들로 구성되어있다.
version:
version: '3'
3만 쓰게 되면 가장 최신 버전으로 인식. 구체적으로 버전을 명시할 수 있다.
services:
서비스들에 대한 정보 명시
container_name:
container_name: "local-mongodb"
컨테이너명 명시
image:
image: mongo
가져올 이미지 명시
restart:
restart: always
컨테이너 종료 -> 재실행
environment:
environment: MONGO_INITDB_DATABASE: local-db MONGO_INITDB_ROOT_USERNAME: root MONGO_INITDB_ROOT_PASSWORD: password
컨테이너의 환경변수 명시
ports:
ports: - "27017:27017"
포트 매핑 정보 명시. (호스트:컨테이너)
volumes:
volumes: - "local-mongodb:/var/lib/mongo"
볼륨 매핑 (호스트:컨테이너)
\
docker-comopse로 mongodb, mysql, redis 환경 세팅하기
본 예시에서는 mongodb, mysql, redis 를 포함하는 컨테이너를 docker-comopse를 사용하여 설치한다.
docker-compose up으로 컨테이너 띄우기
docker-compose 파일이 있는 위치로 이동하여 해당 파일을 실행시킨다. (첨부파일의 docker-compose.yml 파일을 다운받으면 된다.)
docker-compose up -d(-d 옵션: 백그라운드에서 돌아갈수 있도록 한다.)
해당 명령어는 파일이름이 docker-compose.yml인 경우에 사용가능하고, 파일 이름이 다른 경우라면 다음의 명령어를 사용하면 된다.
docker-compose -f docker-compose-test.yml up
docker-compose -f {파일이름} up(-f 옵션: 기본으로 제공하는 docker-compose.yml이 아닌 별도의 파일명을 실행할 때 사용)
제대로 컨테이너가 띄워졌다면 다음과 같은 화면을 볼 수 있다.
docker image 확인하기
다음의 명령어를 입력하여 docker image를 확인할수 있다.
docker images -a(-a 옵션: 실행중이지 않더라도 전체 리스트를 보여줌)
방금전 docker-compose up을 하면서 다운받은 mongo, redis, mysql 이미지가 있는것을 확인할 수 있다.\
docker process 확인하기
다음의 명령어를 입력하여 docker에 떠있는 process를 확인할수 있다.
docker ps -a(-a 옵션: 실행중이지 않더라도 전체 리스트를 보여줌)
방금전 docker-compose up으로 실행시킨 mongo, redis, mysql 이미지가 있는것을 확인할 수 있다.\
docker-compose down으로 컨테이너 내리기
다음의 명령어를 입력하면 해당 파일로 띄운 컨테이너를 내릴 수 있다.
docker-compose downmongodb의 docker-compose.yml
version: '3'
services:
local-mongodb:
container_name: "local-mongodb"
image: mongo
restart: always
environment:
MONGO_INITDB_DATABASE: local-db
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: password
ports:
- "27017:27017"
volumes:
- "local-mongodb:/var/lib/mongo"
volumes:
local-mongodb:간단한 MongoDB 명령어
mongo admin -u [유저명] -p [비밀번호]
mongo admin -u root -p password
mongodb 접속
use [데이터베이스명]
use mydb
데이터베이스 생성 & 사용
show dbs
데이터베이스 조회
db
현재 사용중인 DB 조회
db.createCollection("[컬렉션명]")
db.createCollection("person")
collection 생성
show collections
collection 조회
db.[컬렉션명].insert([JSON format])
db.person.insert({"name" : "hyoung", "email" : "[joonhyuck-hyoung@nhn-commerce.com](mailto:joonhyuck-hyoung@nhn-commerce.com)"})
document(데이터) 생성
db.[컬렉션명].find()
db.person.find()
document 조회
db.[컬렉션명].remove([JSON format])
db.person.remove({"name":"hyoung"})
document 삭제
db.[컬렉션명].drop()
db.person.drop()
collection 삭제
\
mysql의 docker-compose.yml
local-mysql:
image: mysql/mysql-server:8.0.23
container_name: local-mysql
hostname: local-mysql
restart: always
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: accounts
MYSQL_USER: user
MYSQL_PASSWORD: password
MYSQL_DATABASE: authorization
volumes:
- "local-mysql:/var/lib/mysql"\
lima에서 docker로 띄운 mysql 접속하기
docker mysql container 접속: $ docker exec -it local-mysql bash
mysql 접속: $ mysql -h localhost -P 13306 -u root -p authorization
redis의 docker-compose.yml
local-redis:
container_name: local-redis
hostname: local-redis
image: redis
restart: always
ports:
- "6379:6379"
volumes:
- "local-redis:/var/lib/"lima에서 docker로 띄운 redis 접속하기
docker redis container 접속: $ docker exec -it local-redis redis-cli\
\
docker volume - mount
도커 컨테이너에서 작성되거나 수정된 파일은 컨테이너가 파기되면 호스트도 함께 삭제된다.
호스트쪽 파일 시스템에 데이터를 마운트하면 컨테이너에서 삭제해도 호스트 파일 시스템에 남아있게 된다.
volume 종류
Bind Mount 호스트 환경의 특정 경로를 컨테이너 내부 볼륨 경로와 연결하여 마운트한다. 이 방법은 보안에 영향을 미칠 수 있음
Volume (가장 일반적) 도커 볼륨은 도커 컨테이너에서 도커 내부에 도커 엔진이 관리하는 볼륨을 생성 생성된 볼륨은 호스트 디렉터리의 /var/lib/docker/volumes 경로에 저장되며, 도커를 사용하여 관리가 용이
tmpfs Mount 호스트의 파일 시스템이 아닌, 메모리에 저장하는 방식을 사용
\
Volume mount 테스트
사전준비 mysql image 가 존재하는 docker-compose.yml 파일
version: '3'
services:
local-mysql:
image: mysql/mysql-server:8.0.23
container_name: local-mysql
hostname: local-mysql
restart: always
ports:
- "13306:3306"
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_USER: user
MYSQL_PASSWORD: password
MYSQL_DATABASE: mydb
volumes:
- "local-mysql:/var/lib/mysql"
volumes:
local-mysql:\
1.MySQL
mysql image 가 존재하는 docker-compose.yml 을 통해 컨테이너 빌드
docker-compose up -d --f실행중인 mysql 컨테이너에 접속
docker exec -it [컨테이너명 or 컨테이너ID] bashmysql 접근
mysql -u [유저명] -p [비밀번호]데이터베이스 사용
use [데이터베이스명];테스트를 위한 테이블 (member_table) 생성
CREATE TABLE member_table (
seq INT NOT NULL AUTO_INCREMENT,
mb_id VARCHAR(20),
mb_pw VARCHAR(20),
address VARCHAR(50),
mb_tell VARCHAR(50),
PRIMARY KEY(seq)
)
6. 더미데이터 추가
INSERT INTO member_table(mb_id, mb_pw, address, mb_tell) VALUES("test", "test", "test", "test");
7. 데이터 확인
SELECT * FROM member_table;
+-----+-------+-------+---------+---------+
| seq | mb_id | mb_pw | address | mb_tell |
+-----+-------+-------+---------+---------+
| 1 | test | test | test | test |
| 2 | test | test | test | test |
| 3 | test | test | test | test |
| 4 | test | test | test | test |
| 5 | test | test | test | test |
| 6 | test | test | test | test |
| 7 | test | test | test | test |
| 8 | test | test | test | test |
| 9 | test | test | test | test |
| 10 | test | test | test | test |
| 11 | test | test | test | test |
| 12 | test | test | test | test |
+-----+-------+-------+---------+---------+
12 rows in set (0.00 sec)
8. mysql 접근 종료
exit
2. volume mount 확인
docker volume 생성 확인
docker volume ls
DRIVER VOLUME NAME
local docker_local-mysql
2. lima 환경 내의 물리적 저장장소 확인
cd ~/.local/share/docker/volumes/
cd _data
접근이 거부되면 sudo -s
3. 테스트용으로 생성한 테이블 (member_table) 확인
root@lima-default:/home/taejun.linux/.local/share/docker/volumes/docker_local-mysql/_data/mydb# ls
member_table.ibd
\
mount 과정 확인 방법
docker-compose down=>docker-compose up이후에도 lima 위에 데이터가 존재하는지 여부 확인docker rm -f [컨테이너명]을 통해 컨테이너를 지워도 lima 위에 데이터가 존재하는지 여부 확인
부록
의문점
mongodb의 데이터는 mysql와 다르게 지정된 volume이 아닌 해시값으로 이루어진 폴더에 저장된다.
taejun@lima-default:~/.local/share/docker/volumes$ cd cea1548f8644bcb41ac708a0b3d204f2616f20a35159f25b42aed9645b6d6197/_data/
taejun@lima-default:~/.local/share/docker/volumes/cea1548f8644bcb41ac708a0b3d204f2616f20a35159f25b42aed9645b6d6197/_data$ ls
WiredTiger collection-0-4752117110476890269.wt index-3-4752117110476890269.wt mongod.lock
WiredTiger.lock collection-2-4752117110476890269.wt index-5-4752117110476890269.wt sizeStorer.wt
WiredTiger.turtle collection-4-4752117110476890269.wt index-6-4752117110476890269.wt storage.bson
WiredTiger.wt collection-7-4752117110476890269.wt index-8-4752117110476890269.wt
WiredTigerHS.wt diagnostic.data index-9-4752117110476890269.wt
_mdb_catalog.wt index-1-4752117110476890269.wt journal\
기존 프로젝트의 docker-compose 파일을 사용할 경우 겪을 수 있는 어려움
기존의 docker image들은 arm64/v8 기반으로 이미지가 생성되어있다. 그렇기에 기존 이미지를 이용하여 컨테이너를 생성하게 될 경우 m1 플랫폼 환경인 linux/x86_64 를 지원하지 않기 때문에 docker-comopse up을 할 경우 에러가 발생한다.
다음과 같은 방법으로 해당 에러를 해결할수 있었다.
docker-compose file 에 다음의 내용을 추가한다.
platform: linux/x86_64이 방법은 해당 이미지가 이미 buildx옵션으로 빌드되어 도커 허브에 존재하는 경우에만 통한다.
2. 해당 이미지를 docker buildx를 이용하여 m1 플랫폼도 지원할수 있도록 재빌드 하여 사용하는 방법 linux/x86_64 도 지원하는 멀티플랫폼 빌드와 관련된 내용은 다음의 링크에서 확인할 수 있다.
Docker buildx build(at M1 Macbook)
이제 해결이 안되는 경우에는 구글링으로...
추가 진행할 내용
현재 redis, mongo, mysql은 m1환경에서 lima를 이용하여 docker-compose 파일을 이용하여 컨테이너를 띄웠지만, kafka + zookeepr의 경우에는 docker-compose 파일을 이용한 컨테이너를 띄우는 것에 어려움을 겪고있다.
해당 부분은 추가적으로 성공하는 데로 본 내용에 추가할 예정이다.
docker-compose를 이용하여 컨테이너를 띄우게 되면 다음과 같은 에러가 나면서 프로세스가 떠있지 못하고 자꾸 죽는 현상을 겪고 있다.
standard_init_linux.go:228: exec user process caused: exec format error출처 : Cho Yoohwa, Kang Sunghyuk, Hyoung Joonhyuck
Last updated