1. Proxy Layer란 

- Proxy Layer : 대리층

- ProxySQL : C++로 짜여진 오픈 소스 Proxy 프로그램으로 총 4개의 database schema를 가지며, Proxy를 컨트롤하고 모니터링할 수 있게 한다.
- Proxy Layer를 두는 이유 : 

앞서서 Orchestra 설정을 해두면 Master(db001)이 샷다운 되더라도 Slave(db002)이 자동으로 Master로 승격되어 고가용성, 곧 시스템이 지속될 수 있도록 할 수 있었다. 하지만, Application 입장에서는, Application의 자체 설정에 따라 기존의 Master(db001)을 계속해서 바라볼 수 있다. 이를 해결하기 위해 중간층인 Proxy Layer를 둘 수 있는데, MySql은 Proxy 프로그램으로 ProxySQL을 사용할 수 있다.

Ex. Spring Boot application-yml에서 Master를 db001로 설정해둔 경우 
--> db001이 샷다운 되고 db002이 자동으로 Master가 되어도
--> Spring Boot는 여전히 db001를 Master로 인식하고 있다.

출처:https://dkswnkk.tistory.com/729

 

2. Docker로 Proxy SQL 생성하기

[1] proxy 디렉토리 생성 및 권한 부여

- ProxySQL 컨테이너도 MySQL 컨테이너와 마찬가지로 호스트 볼륨에 컨테이너 파일이 마운트될 수 있게 해줘야한다.

- 따라서, data 정보가 담길 data 디렉토리와 설정 정보가 담길 conf 티렉토리를 호스트에 생성해준다.

mkdir -p db/proxysql/data db/proxysql/conf
chmod 777 db/proxysql/data db/proxysql/conf
cd db/proxysql/conf

 

[2] proxysql.cnf 생성 후 권한을 644로 부여

- conf 디렉토리에서 proxysql 설정 파일을 만들어준다.

- mysql의 경우 my.cnf로 설정을 작성한다면, proxysql은 proxysql.cnf로 설정을 작성한다.

vi proxysql.cnf
chmod 644 proxysql.cnf

 

datadir="/var/lib/proxysql"
admin_variables=
{
    admin_credentials="admin:admin;radmin:radmin"
    mysql_ifaces="0.0.0.0:6032"
}
mysql_variables=
{
    threads=4
    max_connections=2048
    default_query_delay=0
    default_query_timeout=36000000
    have_compress=true
    poll_timeout=2000
    interfaces="0.0.0.0:6033"
    default_schema="information_schema"
    stacksize=1048576
    server_version="5.5.30"
    connect_timeout_server=3000
    monitor_username="monitor"
    monitor_password="monitor"
    monitor_history=600000
    monitor_connect_interval=60000
    monitor_ping_interval=10000
    monitor_read_only_interval=1500
    monitor_read_only_timeout=500
    ping_interval_server_msec=120000
    ping_timeout_server=500
    commands_stats=true
    sessions_sort=true
    connect_retries_on_failure=10
}

 

[3] docker로 ProxySql 생성

- proxysql 이름을 가지며 호스트명은 proxysql이고, proxysql을 네트워크 alias로 하여 브릿지를 연결한다.

- 호스트 16032 port에서 컨테이너의 6033 port로 연결되며, 

- [1]에서 생성한 호스트의 data, conf로 proxysql의 data파일들과 conf 파일을 영속적으로 연결해준다.

docker run -it --name proxysql -h proxysql \
--net mybridge --net-alias=proxysql \
-p 16032:6032 -p 16033:6033 \
-v /home/opc/db/proxysql/data:/var/lib/proxysql \
-v /home/opc/db/proxysql/conf/proxysql.cnf:/etc/proxysql.cnf \
-d proxysql/proxysql

- Docker 생성 확인 

docker ps --format "table {{.ID}}\t{{.Names}}\{{.Status}}"


[4] ProxySQL 접속(호스트에서 접속하는 것으로, 이 경우 호스트에 mysql 있어야함)

- 여기서 살짝 헤맸는데, 호스트에서 ProxySQL에 직접적으로 접속하기 위해서는 먼저 호스트 OS안에 mysql이 별도로 설치가 되어 있어야 한다. (나는 없었어서 아래 명령어가 에러가 남..)

- MySQL을 설치하고, 아래 명령어를 입력하면 ProxySQL에 접속이 가능하다.

mysql -h127.0.0.1 -P16032 -uradmin -pradmin --prompt "ProxySQL Admin>"

 

3. Proxy Layer 테스트해보기

[1] 먼저 Master 컨테이너 db001에서 테스트 데이버테이스와, 어플리케이션용 user, proxysql용 모니터링 user를 생성한다.

docker exec -it -uroot db001 /bin/bash
mysql -uroot -p

mysql > create user 'appuser'@'%' identified by 'apppass';
mysql > create database testdb default character set utf8;
mysql > grant select, insert, update, delete on testdb.* to 'appuser'@'%'

mysql > create user 'monitor'@'%' identified by 'monitor';
mysql > grant REPLICATION CLIENT on *.* to 'monitor'@'%';

mysql > flush privileges;

 

[2] proxy에서 hostgroup에 db 서버 정보 입력

- proxysql에서 현재 상태와 맞게 쓰기그룹, 읽기 그룹을 형성하고,
 쓰기그룹/읽기그룹을 나누는 기준을 global의 " read_only "로 잡아둔다. (Slave는 global=read_only임)

mysql -h127.0.0.1 -P16032 -uradmin -pradmin --prompt "ProxySQL Admin>"
# 쓰기 그룹(10)
INSERT INTO mysql_servers(hostgroup_id, hostname, port)
VALUES(10, 'db001', 3306);
# 읽기 그룹(20)
INSERT INTO mysql_servers(hostgroup_id, hostname, port)
VALUES(20, 'db001', 3306);
INSERT INTO mysql_servers(hostgroup_id, hostname, port)
VALUES(20, 'db002', 3306);
INSERT INTO mysql_servers(hostgroup_id, hostname, port)
VALUES(20, 'db003', 3306);
# 호스트 그룹 설정
# VALUES(쓰기,읽기,쓰기/읽기 구분 기준, '')
INSERT INTO mysql_replication_hostgroups 
VALUES(10, 20, 'read_only', '');
# 로드
LOAD MYSQL SERVERS TO RUNTIME;
# 설정 영구적인 저장
SAVE MYSQL SERVERS TO DISK;


[3] proxy에서 어플리케이션 user 정보 입력

- Application에서 user:appuser, password:apppass로 ProxySQL에 접속을 요청하면, 

- ProxySQL은 아래에서 설정한 default_hostgroup=10번그룹과 연결을 시도한다.

- 10번은 쓰기그룹이며 Master를 의미하는데, 이는 시스템 상황에 따라 db001 또는 db002로 변경될 수 있다.
  (이때, 구분 기준은 앞서 말했듯 read_only=응/아니 를 기준으로 한다.)

INSERT INTO mysql_users(username, password, default_hostgroup, transaction_persistent)
VALUES('appuser', 'apppass', 10, 0);

LOAD MYSQL USERS TO RUNTIME;

SAVE MYSQL USERS TO DISK;


[4] proxy에서 쿼리 룰 정보 입력 

- 각 호스트 그룹별로 쿼리룰을 설정해준다.

- 기본적으로 모든 쿼리는 [3]에서 설정한 default_hostgroup 인 10번으로 가도록 되어 있는데, 

  아래와 같이 쿼리룰을 설정하면 Select/Update시에 10번으로, Select시에 20번으로 가게된다.

- **쿼리룰 순서가 중요. 반드시 순서대로 해주어야 한다.

INSERT INTO mysql_query_rules(rule_id, active, match_pattern, destination_hostgroup)
VALUES(1, 1, '^SELECT.*FOR UPDATE$', 10);

INSERT INTO mysql_query_rules(rule_id, active, match_pattern, destination_hostgroup)
VALUES(2, 1, '^SELECT', 20);

LOAD MYSQL QUERY RULES TO RUNTIME;

SAVE MYSQL QUERY RULES TO DISK;


[5] 호스트 os 에서 연결  테스트 쉘스크립트 실행

vi app_test_conn.sh
sh app_test_conn.sh

- app_test_conn.sh : hostip주소는 hostname -i로 확인할 수 있는 공인 ip주소를 작성해줘야한다.

# !/bin/bash
while true;
do

  mysql -uappuser -papppass -h{hostip 주소} -P16033 -N -e "select@@hostname,now()" 2>&1| grep -v "Warning"

  sleep 1

done

 

[5] 호스트 os 에서 insert 테스트 쉘스크립트 실행

vi app_test_insert.sh
sh app_test_insert.sh
#!/bin/bash

while true;
do
    mysql -uappuser -papppass -h{{공인ip}} -P16033 -N -e "INSERT INTO testdb.insert_test VALUES ('$(hostname)', NOW())" 2>&1 | grep -v "Warning"
    sleep 1
done

 

[6] 장애 테스트 만들기

세 개의 shell를 연 상태에서 아래와 같이 작업을 수행한다.

(1) sh app_test_insert.sh 로 insert를 지속적으로 실행한다.

(2) slave인 db002에서 읽기를 계속해서 해준다.

(3) docker stop db001로 master db를 stop 시킨다.

그리고 결과를 확인하면, db001에서 insert를 하다가, db002에서 insert를 하는 걸 볼 수 있다.

 

[출처] 인프런 - 따라하며 배우는 MySQL on Docker

[참고]

https://notemusic.tistory.com/55

https://dkswnkk.tistory.com/729

1. 고가용성이란?

- 가용성 = Uptime / (uptime + downtime)

- 고가용성 = 바람직한 정도로 긴 시간 동안 지속적인 운영이 가능한 시스템 또는 컴포넌트 

- 고가용성의 시스템을 구축한다는 건 = 서비스가 다운되는 타임을 최소화하는 시스템을 구축한다는 것

 

2. HA 수동 설정 

[1] Orchestra를 Docker로 생성하기

- Orchestra는 MySQL용 복제 토폴로지 관리자로서, 고가용성 및 복제 관리 툴을 말한다.
- GUI/CLI/API를 통해서 상태를 확인하고 작업을 수행할 수 있다.

docker run -it --name orchestrator -h orchestrator \
--net mybridge --net-alias=orchestrator \
-p 3000:3000 -d openarkcode/orchestrator:latest

 

[2] 도커 컨테이너의 ip 주소 찾기

docker inspect --format '{{.NetworkSettings.Networks.mybridge.IPAddress}}' db001

 

[3] Master에서 Orchestrator에 접속할 수 있는 User 생성

create user orc_client_user@`172.%` identified by 'orc_client_password';
GRANT SUPER, PROCESS, REPLICATION SLAVE, RELOAD ON *.* TO orc_client_user@`172.%`;

 

[4] Orchestrator 접속

- https://{{호스트ip}}:3000/web/clusters 로 접속한다.
- clusters > discover 에 들어가서, 마스터 컨테이너명(db001) : 포트(3306) 를 입력한다.

 

- clusters > dashboard에 들어가면 master가 떠있고 master를 누르면 아래처럼 연결된 slave가 나타난다.

 

3. HA 테스트 진행하기

- read/write 모두 가능한 마스터인 db001가 갑자기 샷다운 된다고 하면

docker stop db001

- master는 리커버리가 필요한 상태가 되며 slave들은 master와 연결이 끊어짐에 따라 read가 불가능해진다. 

-  이때, Recovory를 눌러 db002를 마스터로 직접 승격해주면 db002가 master가 되며 db003이 slave로 붙는걸 볼 수 있다.

- db001를 db002의 slave로 들어가도록 하려면 db001를 재실행한 후, read_only 상태로 변경, db001의 master를 db002로 설정해준다.

docker start db001

docker exec -it -uroot db001 /bin/bash
mysql -uroot -p

mysql> set global read_only=1;
Query OK, 0 rows affected (0.01 sec)

mysql> change master to master_host='db002', \
    -> master_user='repl', master_password='repl', \
    -> master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.31 sec)

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

 

4. HA 자동화(Auto Failover) 하기

[1] Orchestra의 orchestrator.conf.json 파일을 통해 설정 수정하기

[root@dev opc]# docker exec -it orchestrator /bin/bash
bash-4.4# cd /etc/
bash-4.4# vi orchestrator.conf.json

- 아래와 같이 모든 컨테이너에 대해서 Master로 회복이 가능하되, 컨테이너 호스트이름이 db003일 때는 Master로 승격이 되지 않도록 하면, db001/db002는 Master로 회복이 되지만 db003는 Master로 회복이 될 수 없다.

[AS-IS]  [TO-BE]
 "RecoverMasterClusterFilters": [
    "_master_pattern_"
  ],
...
 "PromotionIgnoreHostnameFilters": [],
"RecoverMasterClusterFilters": [
    "*"
  ],
...
 "PromotionIgnoreHostnameFilters": ["db003"],

 

[2] Orchestra를 재실행하여 설정을 초기화한다.

docker restart orchestrator

 

[3] HA 자동화 테스트 해보기 

- 먼저, Audit > Recovery 에서 Failure 상태를 Acknowlege 해준다. (안해주면 정상적인 테스트가 되지 않는다)

- 아까와 마찬가지로 Master인 db002를 stop 시켜 샷다운 상태를 만든다.
- recovery를 누르지 않았으나 db001이 master로 승격된 후 db003이 slave로 붙은 걸 볼 수 있다. 

 

 

[출처] 따라하며 배우는 MySQL on Docker

[참고]

https://velog.io/@makeitcloud/%EB%9E%80-Availability-High-Availability-%EB%9E%80

https://dkswnkk.tistory.com/727

https://jhdatabase.tistory.com/entry/MySQL-Orchestrator-%EA%B5%AC%EC%B6%95-part-1

1. 브리지 생성


[1] 도커 네트워크 확인 & 브리지 생성

[root@dev opc]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
697ad12cd5fa   bridge    bridge    local
d955f1181bf5   host      host      local
30e9346c2d17   none      null      local
[root@dev opc]# docker network create --driver bridge mybridge



[2] data,log 삭제하고 도커 컨테이너 재생성  

docker run -it --name db001 -p 3306:3306 -h db001 \
--net mybridge --net-alias=db001 \
-v /home/opc/db/db001/data:/var/lib/mysql \
-v /home/opc/db/db001/log:/var/log/mysql \
-v /home/opc/db/db001/conf:/etc/percona-server.conf.d \
-e MYSQL_ROOT_PASSWORD="root" -d percona:5.7.30 

docker run -it --name db002 -p 3307:3306 -h db002 \
--net mybridge --net-alias=db002 \
-v /home/opc/db/db002/data:/var/lib/mysql \
-v /home/opc/db/db002/log:/var/log/mysql \
-v /home/opc/db/db002/conf:/etc/percona-server.conf.d \
-e MYSQL_ROOT_PASSWORD="root" -d percona:5.7.30 

docker run -it --name db003 -p 3308:3306 -h db003 \
--net mybridge --net-alias=db003 \
-v /home/opc/db/db003/data:/var/lib/mysql \
-v /home/opc/db/db003/log:/var/log/mysql \
-v /home/opc/db/db003/conf:/etc/percona-server.conf.d \
-e MYSQL_ROOT_PASSWORD="root" -d percona:5.7.30

  

[3] master에서 user 생성 

mysql> CREATE USER 'repl'@'%' IDENTIFIED BY 'repl';
Query OK, 0 rows affected (0.01 sec)

mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
Query OK, 0 rows affected (0.01 sec)



[4] ping 날려보기 

[root@db001 /]# ping db001
PING db001 (172.18.0.2) 56(84) bytes of data.
64 bytes from db001 (172.18.0.2): icmp_seq=1 ttl=64 time=0.047 ms
64 bytes from db001 (172.18.0.2): icmp_seq=2 ttl=64 time=0.043 ms
64 bytes from db001 (172.18.0.2): icmp_seq=3 ttl=64 time=0.044 ms
64 bytes from db001 (172.18.0.2): icmp_seq=4 ttl=64 time=0.044 ms
64 bytes from db001 (172.18.0.2): icmp_seq=5 ttl=64 time=0.043 ms
^C
--- db001 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 3999ms
rtt min/avg/max/mdev = 0.043/0.044/0.047/0.004 ms
[root@db001 /]#
[root@db001 /]# ping db002
PING db002 (172.18.0.3) 56(84) bytes of data.
64 bytes from db002.mybridge (172.18.0.3): icmp_seq=1 ttl=64 time=0.170 ms
64 bytes from db002.mybridge (172.18.0.3): icmp_seq=2 ttl=64 time=0.073 ms
64 bytes from db002.mybridge (172.18.0.3): icmp_seq=3 ttl=64 time=0.078 ms
^C
--- db002 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.073/0.107/0.170/0.044 ms
[root@db001 /]#
[root@db001 /]# ping db003
PING db003 (172.18.0.4) 56(84) bytes of data.
64 bytes from db003.mybridge (172.18.0.4): icmp_seq=1 ttl=64 time=0.102 ms
64 bytes from db003.mybridge (172.18.0.4): icmp_seq=2 ttl=64 time=0.076 ms
64 bytes from db003.mybridge (172.18.0.4): icmp_seq=3 ttl=64 time=0.080 ms
^C


[5] slave 에 master 세팅

mysql> reset master;
Query OK, 0 rows affected (0.02 sec)

mysql> CHANGE MASTER TO MASTER_HOST='db001', \
    MASTER_USER='repl', MASTER_PASSWORD='repl', \
    MASTER_AUTO_POSITION=1;
Query OK, 0 rows affected, 2 warnings (0.02 sec)

mysql> start slave;
Query OK, 0 rows affected (0.01 sec)

mysql> show slave status\G;

>> 결과 

*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: db001
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 635
               Relay_Log_File: db002-relay-bin.000003
                Relay_Log_Pos: 848
        Relay_Master_Log_File: mysql-bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 635
              Relay_Log_Space: 2927711
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 100
                  Master_UUID: edab089d-a7d1-11ee-85d6-0242ac120002
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set: edab089d-a7d1-11ee-85d6-0242ac120002:1-7
            Executed_Gtid_Set: edab089d-a7d1-11ee-85d6-0242ac120002:1-7
                Auto_Position: 1
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
1 row in set (0.01 sec)


 

출처

인프런 - 따라하며 배우는 MySQL on Docker 를 보고 정리해보았습니다.

 

Master/Slave 구조를 사용하는 이유

서버에 트래픽이 몰려들 때 해결하는 방법으로,

컴퓨터 성능을 1) Scale-up 하거나, 컴퓨터를 여러대 두는 2) Scale-out이 있다. 

DB로 다수의 트랜잭션이 몰리면 race condition이 발생할 수 있다.

 

Replication(복제)으로 Master/Slave 구조를 형성하면 DB에 가해지는 부하를 분산하여 이러한 race condition을 미연에 방지할 수 있다. 일반적으로 Master에서 write(쓰기)를 하도록 하고, Slave에서는 read(읽기)를 하도록 하여, 부하를 분산한다. 

 

MySQL에서 Master/Slave가 동작하는 방식은 아래와 같다.

[1] Insert/Update/Delete 트랜잭션이 들어오면 Master에서 이를 처리하고 Binary Log에 변경사항을 기록한다.

[2] Master Thread가 비동기로 Binary Log를 읽어 Slave 서버로 전송한다.

[3] Slave의 I/O Thread는 [2]에서 전달한 Binary Log를 Relay Log에 저장한다.

[4] Slave의 SQL Thread는 [3]에서 저장한 Relay Log를 읽어 Storage engine에 최종 적용한다. 

출처:서버 분산 처리 환경에서 MySQL을 MasterSlave로 이중화하기(링크하단참조)

 

Binary Log는 my.cnf에서는 binlog라는 명칭으로 사용되는데,

MySQL에서 발생하는 모든 변경사항을 담고 있는 로그 파일을 말한다. 

MySQL의 디폴트 설정값에서는 이 Binary Log가 비활성화 되어 있기 때문에 my.cnf에 binlog를 활성화해주어야한다.

my.cnf에서 binlog 설정과 관련된 내용은 아래와 같다.

# Master에서 binlog 설정을 꼭 해주어야 binlog 내용을 replica에 전달할 수 있다.

[mysqld]
log_bin=mysql-bin      #binlog의 파일명을 mysql-bin으로 시작하게 설정
binlog_format=ROW      #binlog의 포맷을 row로 설정 (자세한 세팅은 앞선 블로그 내용 참고)
log_slave_updates=ON   #slave업데이트 여부 
expire_logs_days=90    #로그 저장 시간 (지정하지 않으면 로그가 계속 쌓인다)

 

 

Docker를 통해 Master/Slave 서버 구축하기

[1] 호스트 OS에서 Master와 Slave my.cnf 파일 설정하기 

db/db001, db/db002, db/db003 경로를 각각 만든 후에, 각 경로에 data, log, conf 디렉토리를 만들고, 권한을 777 준뒤,

conf 디렉토리에 my.cnf 파일을 각각 만들어 주었다. 

 

Master인 db001의 my.cnf 파일은 아래와 같다. 

[mysqld]
server-id=100              <-- server-id는 master, slave가 달라야한다.              
report_host=db001                
basedir=/var/lib/mysql            
datadir=/var/lib/mysql            
socket=/var/lib/mysql/mysql.sock   
log_bin=mysql-bin          <-- master에 log_bin 설정은 필수!
binlog_format=ROW                 
log-error=/var/log/mysql/mysql.log             
gtid_mode=ON                       
enforce-gtid-consistency=true               
symbolic-links=0
pid-file=/var/run/mysqld/mysqld.pid 
expire_logs_days=90       <-- log는 최대 90일만

[mysqld_safe]
socket=/var/lib/mysql/mysql.sock
pid-file=/var/run/mysqld/mysqld.pid
nice=0

 

Slave의 my.cnf 파일은 아래와 같다.

[mysqld]
server-id=300                        <-- slave id는 master와 달라야한다.
report_host=db003                
basedir=/var/lib/mysql            
datadir=/var/lib/mysql            
socket=/var/lib/mysql/mysql.sock   
log_bin=mysql-bin          
binlog_format=ROW                 
log-error=/var/log/mysql/mysql.log             
gtid_mode=ON                       
enforce-gtid-consistency=true     
log_slave_updates=ON                  <-- relay log 정보를 slave bin log에도 저장          
symbolic-links=0
pid-file=/var/run/mysqld/mysqld.pid 
expire_logs_days=90

[mysqld_safe]
socket=/var/lib/mysql/mysql.sock
pid-file=/var/run/mysqld/mysqld.pid
nice=0

 

[2] Docker를 통해 Master, Slave MySQL 서버를 각각 생성하기 ([1]의 my.cnf 파일 경로 마운트)
Master는 미리 만들어둬서, Slave를 두개 더 만들어줬다.

[root@dev opc]# docker run -it --name db002 -p 3307:3306 -h db002 -v /home/opc/db/db002/dat    a:/var/lib/mysql -v /home/opc/db/db002/log:/var/log/mysql -v /home/opc/db/db002/conf:/etc/percona-server.conf.d -e MYSQL_ROOT_PASSWORD="root" -d percona:5.7.30
[root@dev opc]# docker run -it --name db003 -p 3308:3306 -h db003 -v /home/opc/db/db003/dat    a:/var/lib/mysql -v /home/opc/db/db003/log:/var/log/mysql -v /home/opc/db/db003/conf:/etc/percona-server.conf.d -e MYSQL_ROOT_PASSWORD="root" -d percona:5.7.30

 

[3] Master 컨테이너에서 Replication User생성하기

Docker를 통해 Master 컨테이너의 MySQL에 접속한 뒤,

[root@dev opc]# docker exec -it -uroot db001 /bin/bash
[root@db001 /]# mysql -uroot -p

Slave에서 Master MySQL에 접속할 수 있도록 User를 하나 생성한 뒤, Replication 권한을 줬다.

mysql> CREATE USER 'repl'@'%' IDENTIFIED BY 'repl';
Query OK, 0 rows affected (0.01 sec)

mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
Query OK, 0 rows affected (0.01 sec)

그리고 ifconfig를 통해 Master의 ip주소를 확인했다. 

ifconfig

 

[4] Slave 컨테이너에서 Master 지정하기 

Slave 컨테이너의 MySQL에 접속하는 방법은 동일하다.(위 참조)

[3]에서 확인한 Master MySQL의 ip/user 정보를 통해 master를 지정해준다. 

mysql> reset master;
Query OK, 0 rows affected (0.04 sec)

mysql> CHANGE MASTER TO MASTER_HOST='{{Master의 ip주소}}', \
    -> MASTER_USER='repl', MASTER_PASSWORD='repl', \
    -> MASTER_AUTO_POSITION=1;
Query OK, 0 rows affected, 2 warnings (0.02 sec)

그리고 slave를 시작한 후, 상태를 확인하면 Master가 제대로 지정된 걸 확인할 수 있었다.

start slave;

show slave status\G;
# 결과에 아래 내용이 있다면 slave 적용 완료됨 
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

 

[5] 테스트해보기

Master, Slave에 동일명의 database와 테이블을 생성한 뒤, Master에서 insert 작업 후, Slave에서 확인한다.

 

[참고]

- 서버 분산 처리 환경에서 MySQL을 MasterSlave로 이중화하기

- https://jupiny.com/2017/11/07/docker-mysql-replicaiton/

 

 

호스트 OS에 log/config를 연결하기 위한 순서

[1] 호스트 OS에서 log,conf 파일 경로를 먼저 생성
[2] mysql 기본 설정 파일(my.cnf)을 호스트 OS의 conf 경로에 저장
     * 주의 ) 이 때, my.cnf 파일의 설정값은 컨테이너를 기준으로 한다.
       예를 들어, basedir=/var/lib/mysql 로 설정한다면, 이는 컨테이너의 /var/lib/mysql 경로를 의미한다. 
[3] 컨테이너를 재생성하며 -v 옵션을 통해 호스트 OS의 log/conf 경로와 컨테이너 log/conf 경로를 연결
     * my.cnf 에서 설정했던 log 경로가 곧 컨테이너 log 경로이다. 
       컨테이너 conf 경로는 my.cnf이 저장되는 아무 경로로 설정하면 된다.

 

호스트 OS에 log/conf 파일 경로 생성

기존 컨테이너는 삭제하고, 새로 data, log, config 를 저장할 경로를 생성한뒤 각 경로에 권한을 777로 설정했다.

# 경로 생성
mkdir db/db001/data db/db001/log db/db001/conf

# 권한 설정 
chmod 777 db/db001/data db/db001/log db/db001/conf

 

 

호스트 OS의 config 경로에 MySQL 기본 설정 파일 생성 - my.~~

MySQL에서는 기본 설정값을 my로 시작하는 파일에 담아 둔다. 

- 유닉스 계열 : my.cnf

- 윈도우 : my.ini

Docker 컨테이너에서 아래의 명령어를 치고 디폴트로 잡힌 my.cnf 파일 경로를 확인했다. 

docker exec db001 mysql --help

/etc/my.cnf부터 /etc/mysql/my.cnf, /usr/etc/mysql... 경로들 중에서 어딘가에 my.cnf이 있다는 거다.

(내 컨테이너 안에서는 확인해보니 /etc/my.cnf 경로에 my.cnf 파일이 담겨 있었다.)

Default options are read from the following files in the given order:
/etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf

docker container 또한 앞서 말했듯 일종의 게스트 OS로 자신만의 분할 공간을 가지고 있기에,
docker container 내의 파일을 열어보기 위해서는 docker container의 쉘을 열어줘야 한다.
Unix 계열의 OS의 경우, sh/bash/zbash 의 쉘 종류들이 존재하는데, 그 중 bash를 사용하면 된다.
docker를 exec로 실행할 때, /bin/bash를 붙이면 해당 Container의 bash쉘을 실행시키겠다는 뜻이다.

[root@sideproject opc]# docker exec -it -uroot db001 /bin/bash


(mysql container의 mysql를 다이렉트로 실행하기 위해서는 docker exec -it {컨테이너명} mysql -uroot -p를 쓴다)

사이드로 빠진 얘기는 차치하고, 다시 /etc/my.cnf의 my.cnf 파일을 확인해보면 아래와 같다.

[root@db001 /]# cat /etc/my.cnf
#
# The Percona Server 5.7 configuration file.
#
#
# * IMPORTANT: Additional settings that can override those from this file!
#   The files must end with '.cnf', otherwise they'll be ignored.
#   Please make any edits and changes to the appropriate sectional files
#   included below.
#
!includedir /etc/my.cnf.d/
!includedir /etc/percona-server.conf.d/

해석하면, 

* 중요 : 이 파일을 통해 추가적인 세팅들을 덮어쓸 수 있다!
  파일들은 항상 .cnf 확장자로 끝나야 하며, 그렇지 않으면 무시된다.
  아래 경로들에 있는 부분 섹션 파일들과 같이 적절한 방식으로 작성해두어라.
!includedir /etc/my.cnf.d/
!includedir /etc/percona-server.conf.d/

하라는 대로 하기 위해서, 제시된 경로들을 확인해보니 파일이 딱 하나 있었다.

mysql 또한 하나의 소프트웨어 프로그램이기 때문에 client와 server가 존재하며,

my.cnf에 쓰는 mysql이 client 프로그램이고, mysqld가 server(=데몬) 프로그램을 의미했다.

아래의 mysqld는 그 중 서버 프로그램(이자 데몬 프로그램)을 말한다. 

# /etc/my.cnf.d/docker.cnf 파일 
# mysql의 background 설정
[mysqld]
skip-host-cache
skip-name-resolve

 

my.cnf 파일 구성하기

 

[ 시작 전에 - mysql의 동작 방식에 대해 간단히 살펴보기 ] 

mysql은 내부적으로 클라이언트 프로그램(mysql), 서버 프로그램(mysqld)를 두며,
socket을 통해 클라이언트-서버 간 양방향 통신을 한다.
이 때, socker 통신 방식으로 크게 두 가지의 방식을 사용한다. 
1) TCP/IP 통신 : 서버-클라이언트가 다른 컴퓨터에 있을 때 사용 
2) Unix Domain Socker 통신 : 서버-클라이언트가 같은 컴퓨터에 있을 때 mysql.sock 파일을 통해 통신
mysql를 로컬 컴퓨터에서 docker로 생성해줬기 때문에 지금 내 경우 mysql은 2)과 같이 socket 통신을 한다.
이 때 mysql.socket이 위치한 경로는 디폴트로 /var/lib/mysql/mysql.sock 이다.

mysql의 Replication(복제방식)은 여러가지가 있으며, 그 중 Async Replication은 Binary Log를 활용해 Replica를 형성한다.
Slave에서는 상위(ex.Master)로부터 로그를 받아 relay log에 저장하는데, 만약 log_slave_updates 파라미터가 활성화(ON)되어 있다면 이 로그를 자신의 binlog에도 함께 기록한다.

출처:https://hoing.io/archives/3111

정말 아름답게도 my.cnf 파일의 모든 옵션을 정리해준 블로그글이 있었다(갓),
그 중에 당장 필요한 것만 뽑았는데 세밀한 옵션 설정이 필요하다면 나중에 또 이분의 글을 참고하면 도움이 될 것 같다.

https://youngsam.net/entry/mysql-mycnf-%EB%82%B4%EC%9A%A9-%EC%84%A4%EB%AA%85-%EC%A0%95%EB%A6%AC

 

영삼넷 :: mysql my.cnf 내용 설명 정리

my.cnf : The file has system variables for DB environment. location of MariaDB SW in this docoment : /engn001/mysvc01/mariadb-10.0.26 location of my.cnf in this document: /engn001/mysvc01/MARIASVC/my.cnf my.cnf sample $ vi /engn001/mysvc01/MARIASVC/my.cnf

youngsam.net

# Mysql 서버 옵션
[mysqld]
server-id=1                        # 서버 id값/master,slave들이 서로 달라야함
report_host=db001                  # 호스트명
basedir=/var/lib/mysql             # 기본 경로 
datadir=/var/lib/mysql             # 데이터 저장 위치
socket=/var/lib/mysql/mysql.sock   # 소켓 파일 경로 
log_bin=mysql-bin                  # binlog(서버 내 모든 변경 내역) mysql-bin.0001 형식으로 저장
binlog_format=ROW                  # binlog 저장 방식 - statement/row/mixed 
                                # row : binary / statement : sql query / mixed : statement+row
log-error=/var/log/mysql/mysql.log # 에러 로그 경로                  
gtid_mode=ON                       # 트랜잭션 고유 식별자 ON
enforce-gtid-consistency=true      # gtid on할 때 DDL명령어 안되는 것 강제 해제
log_slave_updates                  # Slave라면 ON으로 자신의 binlog에 로그 저장
symbolic-links=0 # Disabling symbolic-links is recommended to prevent assorted security risks
pid-file=/var/run/mysqld/mysqld.pid # 프로세스 id 파일 경로 설정 (꼭 mysqld_safe에도 넣어야함)

# Mysqld_safe : mysqld를 감시하는 데몬으로, mysqld_safe가 mysqld를 실행한다.
[mysqld_safe]
socket=/var/lib/mysql/mysql.sock
pid-file=/var/run/mysqld/mysqld.pid
nice=0

conf 디렉토리에 my.cnf파일을 vi로 넣어두었다.  또 권한을 644(rw-r-r) 로 두었다. 

vi my.cnf

// rw-r-r 로 권한 설정
chmod 644 my.cnf

이제, 컨테이너를 재생성 해준다. 

 

컨테이너 재생성 및 실행 

# 컨테이너 생성
docker run -i -t --name db001 -h db001 -p 3306:3306 \ 
-v /home/opc/db/db001/data:/var/lib/mysql \ 
-v /home/opc/db/db001/log:/var/log/mysql \ 
-v /home/opc/db/db001/conf:/etc/percona-server.conf.d \       <--- 설정 파일 
-e MYSQL_ROOT_PASSWORD="root" -d percona:5.7.30

# 참고) 오라이클 클라우드를 쓰면 /home/opc/ 를 입력해줘야 처음 사용자 접속 경로에서 내려간다.

 

이 상태에서, /db/db001/log 로 가면, 아래와 같이 mysql.log가 잘 들어간 걸 볼 수 있었다.

[root@sideproject log]# ll
total 8
-rw-r-----. 1 polkitd input 4133 Dec 29 11:57 mysql.log

 

[참고]

인프런 > 따라하며 배우는 MySQL on Docker 를 듣고 정리한 내용

https://hoing.io/archives/3111

https://kihyun-log.tistory.com/entry/MySQL-binlog-format
https://antamis.tistory.com/9

https://velog.io/@inhwa1025/MySQL-%EC%84%A4%EC%A0%95-%ED%8C%8C%EC%9D%BC-my.cnf-%EC%98%B5%EC%85%98-%EC%A2%85%EB%A5%98

Docker와 VM의 차이

* VM : Virtual Machine 가상 머신으로, 분할 공간의 가상 환경을 제공한다.

* 호스트 OS : 서버 OS 

* 게스트 OS : VM이 서버 OS위에 올리는 가상 OS

* 하이퍼바이저 : 게스트 OS를 구동하고 모니터링하는 소프트웨어
  -> 유형 1 : Native/Bare-Metal 하이퍼바이저, 호스트 OS 없이 게스트 OS들만 존재
     ex. VMware의 ESXi, Citrix의 Xen, Microsoft의 Hyper-V
  -> 유형 2 : Hosted 하이퍼바이저, 호스트 OS 위에 게스트 OS들을 둔다. 
     ex. VmWare의 Workstation, Oracle의 VirtualBox

 

출처:https://velog.io/@kdaeyeop/%EB%8F%84%EC%BB%A4-Docker-%EC%99%80-VM%EC%9D%98-%EC%B0%A8%EC%9D%B4

 

가상 머신(VM)의 경우, 하이퍼바이저를 통해 호스트 OS 위에 게스트 OS들을 두거나, 호스트 OS 없이 게스트 OS들을 사용할 수 있도록 분할된 가상 환경을 제공한다. 이 경우, 각각의 분할된 OS 마다 자원을 할당해주어야 한다.
도커(Docker)의 경우, 이와 달리 하나의 호스트 OS 의 커널을 각각의 컨테이너가 공유하는 형태를 띈다. 


Docker의 컨테이너가 독립된 공간을 가질 수 있는 이유

Docker는 기본적으로 리눅스를 기반으로 만들어진 오픈 소스 프로그램이다. 
리눅스 커널의 Cgroup은 프로세스들이 쓸 수 있는 사용량을 제한하며, Name space는 각 프로세스가 볼 수 있는 범위를 제한한다. (자세한 내용은 아래 참고 링크 확인) 도커는 이러한 리눅스의 특성을 활용해 Container를 구성했고, 각 Container는 따라서 마치 게스트 OS와 같이 독립된 공간을 가질 수 있다. 



리눅스에서 Docker 설치하기 

나는 윈도우를 쓰고 있지만 도커는 Linux 기반이기에...

오라클 클라우드 리눅스 OS에 접속해 아래와 같이 Docker를 설치해줬다. 

yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y docker-ce
systemctl start docker
docker --version

 

OS가 리눅스가 아니면 홈페이지를 통해 Docker를 다운받을 수도 있었다.

https://www.docker.com/get-started/

 

Docker를 통해 컨테이너 생성

docker run -i -t --name [db이름] -e MYSQL_ROOT_PASSWORD="비밀번호" -d persona:5.7.30
// -it : 컨테이너에 쉘로 접속하기 위한 옵션
// --name : 컨테이너 이름 할당 
// -e : 환경변수 세팅 
// -d : 백그라운드로 컨테이너 실행

 

> Docker는 image만 있다면 어디서든지 컨테이너 생성이 가능하다.

> 컨테이너는 가상 머신과 마찬가지로 가상 IP 주소를 할당 받으며, 기본적으로 172.17.0.x의 IP를 순차적으로 할당한다. 

docker run -it --name network_test ubuntu:14.04

  * 위와 같이 -p 옵션이 없이 docker를 실행하면, 이 컨테이너는 외부에서 접속을 할 수 없고, 호스트에서만 접속이 가능하다.
> 따라서, 외부에서 접근을 할 수 있도록 하려면 이 컨테이너에 -p 옵션을 두고 {호스트port}:{도커port} 로 연결하거나, {외부IP:port}:{도커port} 로 연결하도록 해야한다.

docker run -it --name network_test -p {ip:port}:{port} ubuntu:14.04

 

원격으로 MySQL Container 접속하기

호스트의 3306 포트에서 컨테이너의 3306 포트로 연결하여, 호스트에서 컨테이너의 mysql를 접속할 수 있게 한다면,
아래와 같이 코드를 작성하면 된다. 

-- docker container 생성
docker run -it --name db001 -e MYSQL_ROOT_PASSWORD="root" -p 3306:3306 -d percona:5.7.30

-- percona에서 mysql 이미지를 다운로드한다.
https://docs.percona.com/percona-server/8.0/yum-download-rpm.html

 

> 이제 호스트OS 3306에서 컨테이너 3306로 MySQL 접속이 가능하게 됐다.  

> 하지만 위의 경우, 컨테이너를 삭제하면 컨테이너 계층의 mysql 데이터 또한 삭제되게 된다. mysql 처럼 데이터의 영속성이 중요한 경우 이와 같이 컨테이너-영속성 데이터가 종속관계가 되어서는 안된다.

  * mysql의 데이터는 기본적으로 /var/lib/mysql 경로에 저장하는데,
    Docker 컨테이너 안의 /var/lib/mysql 에 데이터가 저장되어, 컨테이너를 삭제하면 /var/lib/mysql 데이터가 유실된다. 
> 이를 막기 위한 방법은, 컨테이너와 독립적으로 데이터를 저장하는 것이다. 이때, 볼륨이라는 개념을 이해해야하는데, 볼륨은 운영체제에서 논리 드라이브(local drive)라고도 불리는 것으로, SSD와 같은 물리 드라이브와 달리 논리적으로만 존재하는 드라이브를 말한다. 대표적으로 C드라이브가 이 볼륨에 해당된다.
> 볼륨을 컴퓨터가 사용할 수 있도록 적용하는 과정을 마운트라고 하는데, 컨테이너가 삭제되더라도 데이터를 유지하기 위해서는, 호스트 OS로부터 컨테이너로 볼륨를 마운트해야 한다. 

> 볼륨을 마운트하는 방법은 크게 세가지가 있다.
   1) 호스트와 볼륨을 공유하는 방법   

   2) 볼륨 컨테이너를 활용하는 방법
   3) 도커가 관리하는 볼륨을 사용하는 방법 

출처 :&nbsp; 3. Docker Volume (tistory.com)

 

Docker Volume

1. 호스트와 볼륨 공유
-v 옵션을 통해 호스트 OS의 특정 디렉토리와 컨테이너의 특정 디렉토리를 공유할 수 있다. 

// 먼저 호스트에 디렉토를 생성한다.
mkdir -p /db/db001/data

// 호스트 디렉토리의 권한을 수정한다.
chmod 777 /db <-- /db 하위 폴더까지 권한 수정

// -v {호스트디렉토리}:{컨테이너디렉토리}
docker run -it --name db001 -p 3306:3306 \
-v /db/db001/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD="root" -d percona:5.7.30

 

2. 도커 볼륨 

이건 percona 사이트에서 권장하는 방식이기도 한데,
* percona에서 권장하는 docker를 통한 mysql 설치 https://docs.percona.com/percona-server/8.0/quickstart-docker.html

 

먼저 docker volume create로 볼륨을 생성한다.

docker volume create --name {볼륨 이름}


그리고 나서 volume ls로 볼륨을 조회하면 아래와 같이 볼륨 내역이 나타난다.

[root@sideproject opc]# docker volume ls
DRIVER    VOLUME NAME
local     ec9de5f4574d28879fead241b36addffc99ae8390048546c07ac2067265e8e56
local     mysqlVolume
local     myvol

이후 docker run과 함께 -v 옵션에 {호스트의 volume 이름}:{컨테이너 경로}를 넣어주면 Container안의 /var/lib/mysql 경로와 호스트의 /var/lib/docker/volumes/{볼륨이름}/_data와 마운트를 해준다. 

docker run -it --name db001 -p 3306:3306 \
-v myvolume:/var/lib/mysql\
-e MYSQL_ROOT_PASSWORD="root" -d percona:5.7.30

// 옵션 설명 
// --name : 컨테이너 이름 
// -d : detached container (백그라운드에서 동작한다)
// -e : 환경설정
// --volume : 영속적인 데이터베이스 스토리지 생성

아래의 명령어를 통해 확인해보니, /var/lib/docker/volumes의 하위로 호스트 경로가 생성되는 걸 볼 수 있었다. 

[root@sideproject opc]# docker inspect --type volume mysqlVolume
[
    {
        "CreatedAt": "2023-12-28T13:48:57Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/mysqlVolume/_data",
        "Name": "mysqlVolume",
        "Options": null,
        "Scope": "local"
    }
]

이제 도커로 mysql에 접속을 해본다. 접속이 잘된다.

docker exec -it psmysql mysql -uroot -p

호스트에서 cd로 /var/lib/docker/volumes/{볼륨이름}/_data로 가니 mysql 데이터가 나타난다.

[root@sideproject _data]# ll
total 96708
-rw-r-----. 1 1001 1001       56 Dec 28 14:45 auto.cnf
-rw-r-----. 1 1001 1001      180 Dec 28 14:46 binlog.000001
-rw-r-----. 1 1001 1001       16 Dec 28 14:46 binlog.index
-rw-------. 1 1001 1001     1705 Dec 28 14:45 ca-key.pem
-rw-r--r--. 1 1001 1001     1120 Dec 28 14:45 ca.pem
-rw-r--r--. 1 1001 1001     1120 Dec 28 14:45 client-cert.pem
-rw-------. 1 1001 1001     1705 Dec 28 14:45 client-key.pem
-rw-r-----. 1 1001 1001   196608 Dec 28 14:46 #ib_16384_0.dblwr
-rw-r-----. 1 1001 1001  8585216 Dec 28 14:45 #ib_16384_1.dblwr
-rw-r-----. 1 1001 1001     5625 Dec 28 14:46 ib_buffer_pool
-rw-r-----. 1 1001 1001 12582912 Dec 28 14:46 ibdata1
-rw-r-----. 1 1001 1001 12582912 Dec 28 14:46 ibtmp1
drwxr-x---. 2 1001 1001     4096 Dec 28 14:46 #innodb_redo
drwxr-x---. 2 1001 1001      187 Dec 28 14:46 #innodb_temp
drwxr-x---. 2 1001 1001      143 Dec 28 14:45 mysql
-rw-r-----. 1 1001 1001 31457280 Dec 28 14:46 mysql.ibd
drwxr-x---. 2 1001 1001     8192 Dec 28 14:45 performance_schema
-rw-------. 1 1001 1001     1705 Dec 28 14:45 private_key.pem
-rw-r--r--. 1 1001 1001      452 Dec 28 14:45 public_key.pem
-rw-r--r--. 1 1001 1001     1120 Dec 28 14:45 server-cert.pem
-rw-------. 1 1001 1001     1705 Dec 28 14:45 server-key.pem
drwxr-x---. 2 1001 1001       28 Dec 28 14:46 sys
-rw-r-----. 1 1001 1001 16777216 Dec 28 14:46 undo_001
-rw-r-----. 1 1001 1001 16777216 Dec 28 14:46 undo_002

 

3. 묵시적인 볼륨 생성

-v 옵션으로 컨테이너 경로만 적어주고 볼륨명은 설정하지 않을 수도 있다.

이 경우, ddab0e38151fcbf21f049846c07c081c8c7b111ace4217afed91cd9014e81ab4 와 같이 볼륨명이 자동으로 생성된다. 호스트 경로에 위 볼륨명이 같이 붙기 때문에 경로가 엄청 길어져서 별로 권장되지는 않는 방식이다.

docker run -it -p 3306:3306 \
--name mysqlVolumeAuto \
-v /db/db001/data3 \
-e MYSQL_ROOT_PASSWORD="root" -d percona:5.7.30

 

 

[정리해보기] Docker 명령어 모음

// 컨테이너 풀
docker pull ubuntu:16.04

// 포어그라운드 실행
docker run -i -t ubuntu:16.04 bin/bash

// 이름 할당 
docker run -i -t --name my_ubuntu ubuntu:16.04 /bin/bash

// 컨테이너 포트 포워딩 
docker run -i -t --name my_ubuntu -p 80:80 /bin/bash

// 데몬으로 실행 
docker run -d -p 80:80 nginx 

// 컨테이너 종료 
exit

// 컨테이너 나오기
Ctrl + P,Q

// 컨테이너 목록 확인 
docker ps -a(모두확인)

// 컨테이너 중지 
docker stop my_ubuntu

// 컨테이너 중지 및 삭제 
docker rm -f my_ubuntu 

// 컨테이너 종료 시 자동 삭제 
docker run -i -t --rm my_ubuntu ubuntu:16.04

// 이미지 목록 
docker images

// 이미지 삭제 
dockr rmi ubuntu:16.04

[출처 : https://dongle94.github.io/docker/docker-basic-use/ ]

 

 

 

참고 
https://developer-cheol.tistory.com/29
3. Docker Volume (tistory.com)
https://selog.tistory.com/entry/%EA%B0%80%EC%83%81%ED%99%94-%EA%B0%80%EC%83%81%EB%A8%B8%EC%8B%A0VM%EA%B3%BC-%ED%95%98%EC%9D%B4%ED%8D%BC%EB%B0%94%EC%9D%B4%EC%A0%80-%EC%89%BD%EA%B2%8C-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0
https://velog.io/@whattsup_kim/Linux-Kernel-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EB%A5%BC-%EC%9C%84%ED%95%9C-%EB%A6%AC%EB%88%85%EC%8A%A4%EC%9D%98-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EA%B2%A9%EB%A6%AC-%EA%B8%B0%EB%8A%A5-cgroup-namespace-union-mount
https://velog.io/@kdaeyeop/%EB%8F%84%EC%BB%A4-Docker-%EC%99%80-VM%EC%9D%98-%EC%B0%A8%EC%9D%B4

https://dongle94.github.io/docker/docker-basic-use/

WSL를 통해서 리눅스를 접속 후 Docker를 사용해보려 하는데

이래저래 설정할게 많아 짜증이 나 그냥 클라우드를 써보기로 했다. 

 

AWS는 프리티어 기간이 지나면 비용이 발생하는데, 

사이드프로젝트를 하는데 비용을 내는게 싫어서 무료 클라우드를 찾아봤다.

클라우드 서버는 AWS, Azure, Redhat... 다양하게 있었는데 그 중에서 평생 무료로 쓸 수 있는

오라클 클라우드를 쓰기로 했다.

 

오라클 클라우드에서 무료 인스턴스를 생성하는 방법은 어렵지 않았다.

아래 유투브를 따라하면서 CentOS 인스턴스를 하나 만들어줬다. 

https://www.youtube.com/watch?v=AgJgEnQv6cw

 

Docker 강의를 듣는 중에 리눅스 OS 사용이 필요해서 WSL을 사용하기로 했다.  

 

WSL 이란?

Windows Subsystem for Linux의 줄임말로, 윈도우에서 리눅스를 사용할 수 있게 해주는 서브시스템을 의미한다. 

기존 WSL을 사용하면 윈도우 환경에서도 powershell 등을 통해 linux 명령어를 사용할 수 있게 해주었다. 

WSL2에서는 업데이트된 형태로 하이퍼바이저를 통해 Windows 뿐만 아니라, Linux 또한 사용할 수 있도록 해준다.

* Hypervisor : 다수의 VM을 사용할 수 있도록 연결해주는 소프트웨어  

윈도우에서 WSL를 사용하는 명령어

* 윈도우 10 이상에서만 설치 가능 

wsl --install

 

powershell 또는 cmd 를 관리자 권한으로 열고 위의 명령어를 친 뒤, 재부팅을 해주면 된다.

 

설치를 했는데 오류가 나는 경우 

wsl/callmsi/e_abort

만약에 위와 같은 오류가 나타난다면, 

윈도우 + R 을 누르고 regedit 를 입력한 뒤, 아래와 같이 WslService를 찾아 삭제 후 재부팅 후 재설치를 하면 된다.

  1. Navigate to Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
  2. Look for "WslService" -> Right click on folder icon -> Delete
  3. Restart PC

WSL 실행하기 

윈도우 > WSL 를 검색하면 WSL를 실행할 수 있다. 

 

참고  

https://hirlawldo.tistory.com/137

https://dongle94.github.io/windows/windows-wsl-install/

https://github.com/microsoft/WSL/issues/10764

티스토리 서버가 터진 이후 한동안 노션으로 스터디 기록을 했습니다. 

사실 아래보다 더 끄적끄적댄 것들이 많은데 일단 여기까지만 한 번.. 공유 해봅니다아..

 

|  노션 북스터디 기록

 

1. 운영체제 곰책 정리

https://simdev1234.notion.site/3c35815411cf42fc8911bb985a435f47

 

운영체제

- 강의 링크 : http://www.kocw.net/home/cview.do?cid=3646706b4347ef09

simdev1234.notion.site

 

2. 클린코드 

https://simdev1234.notion.site/78ad4b26ee2040d4aa4fd0238480b4ca

 

클린코드

A new tool for teams & individuals that blends everyday work apps into one.

simdev1234.notion.site

 

3. 이펙티브 자바 (뒷부분은 너무 귀찮아 정리를 하진... 않았지요..)

https://simdev1234.notion.site/1f185b9eccc3486dabde2bacab6c7c13

 

이펙티브 자바

하위 링크

simdev1234.notion.site

 

4. 스프링부트 핵심

https://simdev1234.notion.site/5e6f03a63ccd45548c86e5518bdcb3cb

 

스프링부트 핵심가이드

A new tool for teams & individuals that blends everyday work apps into one.

simdev1234.notion.site

 

|  기술면접 요약

팀원 분들과 정말 죽도록 많이많이 연습했습니다만, 왜 면접을 가면 정작 아무도 물어보지 않는거지(배부른 소리)

https://simdev1234.notion.site/d38e000e90f94637b56e33f8c60da14a

 

기술면접 요약

참고링크 : ‣

simdev1234.notion.site

 

|  도큐먼트 모음 (이라 읽고 그냥 정리본이라 한다)

https://simdev1234.notion.site/9c741b5bf0454fedb6c92655b363d488

 

도큐먼트 모음

A new tool for teams & individuals that blends everyday work apps into one.

simdev1234.notion.site

 

AWS EC2에 접속하는 방법

https://honglab.tistory.com/179

 

[AWS] AWS EC2에 접속하는 방법 5가지 (SSH, RDP)

팀블로그에 작성한 글입니다 1. 제일 추천 - mobaXterm (SSH, RDP, SFTP 등 한꺼번에 사용 가능) https://err-bzz.oopy.io/223a9c02-7ac2-498c-afde-01db6cf873ae [강추] mobaXterm으로 Linux, Windows Server 접속 mobaXterm이란? err-bzz.

honglab.tistory.com

 

+ Recent posts