1. 程式人生 > >Docker學習+基於Docker MySQL的主從複製

Docker學習+基於Docker MySQL的主從複製

1.Docker學習

1.容器操作:

1.檢視dokcer資訊或版本
 docker info 
 docker -v
2.獲取docker所有命令
 docker help
 獲取命令的引數
 man docker-命令
 eg:獲取 docker run 命令的所有引數
    man docker-run  
3.基於docker映象執行容器
 docker run -i -t --name 容器名 image:tag 程式
 -i 表示以互動方式執行容器
 -t 表示告訴docker為要建立的容器分配一個ty偽終端
 --name 指定建立的容器名,如果無此引數,docker將生成隨機的容器名
 eg: 執行最新版本ubuntu的bash/shell程式
    docker run -i -t ubuntu /bin/bash
4.重啟停止的容器
 docker start [-i] 容器名|容器id
 -i 表示以互動方式重啟
 
 附著到容器上 
 docker attach 容器名|容器id
 
 停止執行的容器
 docker stop 容器名|容器id
 檢視執行的容器
 docker ps
 檢視所有容器
 docker ps -a

5.後臺啟動容器  --- 建立守護式容器
 docker run --name 容器名 -d  映象名 程式
 -d 引數表示 docker將會把容器放到後臺執行,僅返回一個後臺執行的容器id
 eg:在基於ubuntu映象建立的容器111中,執行程式,每秒輸出一個 hello docker,直到容器停止
   docker run --name 111 -d ubuntu /bin/sh -c "while true; do echo hello docker; sleep 1; done"
 
6.刪除所有exited狀態的容器
 docker rm $(docker ps -q -f status=exited)
 說明:
     docker ps -a -f status=exited   查詢所有狀態是exited的容器
     docker ps -q -f status=exited   查詢所有狀態是exited的容器的id

7.檢視容器執行日誌
 docker logs 容器名 | 容器id       列印所有容器執行日誌  
 docker logs -f 容器名 | 容器id    類似  tail -f 動態列印容器執行日誌
 docker logs --tail lines -f 容器名 | 容器id    類似 tail -f --lines  從最後lines行開始,動態列印容器執行日誌
 
 Ctrl + C 退出日誌跟蹤
 
8.容器內的程序
 檢視容器內的程序
 docker top 容器名 | 容器id
 在容器內部執行程序
 docker exec -d 容器名 | 容器id 執行的程序
 說明:
     docker exec 可以在正在執行的容器中進行維護、監控及管理任務
          eg1:
             後臺啟動一個Tomcat容器
             docker run -d --name tom1 tomcat
             檢視tom1容器內的程序
             docker top tom1
             在tom1容器中建立一個檔案
             docker exec -d tom1 touch /ect/test.tom1
          eg2:
             在tom1容器中啟動一個開啟shell的互動任務    ---  進入執行時容器的一種方式
             docker exec -it tom1 /bin/bash   
             在tom1容器中建立一個資料夾
             docker exec -d tom1 mkdir /tom1
        
        9.自動重啟容器
          --restart標誌,讓docker自動重新啟動容器, --restart標誌會檢查容器的退出程式碼,並以此決定是否要重啟容器,Docker預設不會重啟  
          docker run --restart=always --name test1 -d ubuntu /bin/sh -c "while true; do echo hello docker; sleep 1; done"
          解析:
               --restart=always  無論容器的退出程式碼是什麼,Docker都還自動重啟容器
               --restart=on-failure:5  當容器退出程式碼為非0時,Docker會嘗試自動重啟容器,最多重啟5次
         
        10.深入容器
           docker inspect 容器名 | 容器id    檢視容器詳細資訊,對容器進行詳細檢查,返回其配置資訊(名稱、命令、網路配置等資料)
        
        11.刪除容器   --- 必須先停止容器(stop 或 kill)
           docker rm 容器名 | 容器id
           一次性刪除所有容器
           docker rm $(docker ps -a -q)
                 
        12.2個有用的docker容器操作命令:
        
            1.刪除所有已停止的容器
              docker rm $(docker ps -q -f status=exited)
            2.進入後臺執行的容器
              docker exec -it 容器名 /bin/bash
              docker attach 容器名
  
2.映象操作
1.映象:檔案系統的疊加,最底層是引導檔案系統,建立在宿主機核心之上。
      一個映象可以放到另一個映象的頂部,位於下面的映象稱為父映象,以此類推,直到最底部的映象稱為基礎映象
      當從一個映象啟動容器時,Docker會在該映象的最頂層夾雜一個讀寫檔案系統,執行的程式就在這個讀寫層中執行
      當Docker第一次啟動一個容器時,初始的讀寫層是空的,當檔案系統發生變化時,這些變化都會應用到這一層上,
      eg:
         如果想修改一個檔案,這個檔案首先會從該讀寫層下面的只讀層複製到該讀寫層,該檔案的只讀版本依然存在,但已經被讀寫層還總的該檔案副本所隱藏
      
        可寫容器
          |
        Tomcat映象
                   |
                 Ubuntu映象
                   |
                 引導檔案系統
                   |
                 宿主機核心
        2.映象倉庫   docker官方
             docker search 映象    查詢映象
             docker images        列出本地所有映象
             docker pull image:tag  拉取映象,如果沒有tag,預設拉取image映象的最新版本 image:latest
        
        3.構建映象  Dockerfile檔案 + docker build 命令
             1.建立docker hub帳號
             2.docker login 登入
             3.通過Dockerfile建立映象
               eg:建立一個nginx的基礎映象
                  mkdir static_web
                  cd static_web
                  touch Dockerfile
                  編輯Dockerfile內容如下:
                    #Version: 0.0.1
FROM ubuntu:14.04
MAINTAINER Jay He [email protected]
RUN apt-get update
RUN apt-get install -y nginx
RUN echo 'Hi, I am in your container ' > /usr/shar/nginx/html/index.html
EXPOSE 80
 
            4.基於Dockerfile檔案建立映象
              docker build -t="author/image_name:tag" .
              解析:
                  -t  為新映象設定了倉庫和名稱:版本標籤  , 如果沒有指定tag,Docker預設設定為latest標籤
                  .   最後的 . 告訴 Docker到本地目錄中去找Dockerfile檔案,
                      也可通過一個git倉庫的地址來指定Dockerfile位置
                      eg:
                         docker build -t="jay/static_web:v1" [email protected]:xx/docker-static_web
                         
            5.從新映象啟動容器
              docker run -d -p 80 --name static_web jay/static_web:v1 nginx -g "daemon off"
              解析:
                  後臺啟動(適合nginx這樣長時間執行的守護程序)一個名為static_web的容器,
                  同時指定了需要在容器中執行的命令:nginx -g "daemon off" (以前臺執行方式啟動Nginx,作為我們的Web伺服器)   
                  -p 隨機指定一個宿主機port對映到容器中的80埠
                     -p port1:port     將容器的port埠,對映到宿主機的port1埠
                     
            6.Docker指令
                  Dockerfile結構:
    FROM 基礎映象  第一條指令                  
                     MAINTAINER  xx  作者資訊
                     RUN  xx     RUN指令會在當前映象中執行指定的命令,這裡通過RUN指令安裝nginx包,然後建立一個index.html檔案
                     EXPOST port 指定對外的埠


                  CMD 
                               指定一個容器啟動時要執行的命令, 指令會被docker run 命令列 引數 覆蓋
                               類似RUN指令,但:
                                      RUN指令時指定映象被構建時要執行的命令,
                                      CMD 指定容器被啟動時要執行的命令,類似 docker run 啟動容器時,指定要執行的命令
                                      eg:
                                         docker run -it jay/static_web /bin/true
                                         <==>
                                         CMD ["bin/true"]
                                      eg:為要執行的命令指定引數   ---  容器啟動時,列出所有檔案
                                         CMD ["/bin/bash", "-l"]
                              注意:
                                  1.docker run 命令 會覆蓋  CMD指令
                                  2.指定了多條CMD指令,只會執行最後一條
                              
                  ENTRYPOINT
                            指定一個容器啟動時要執行的命令, 指令不會被docker run 命令覆蓋,
                            docker run 命令列中指定的引數都會被當作引數再次傳遞給 ENTRYPOINT指令中指定命令
                            -build 引數  命令 覆蓋配置
                            eg:
                              ENTRYPOINT["jekyll", "build", "--destination=/var/www/html"]
                            eg:
                              ENTRYPOINT ["/usr/sbin/nginx"]
                              ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off;"]  指令指定引數                          
                            
                  ADD
                          用來將構建環境下的檔案和目錄複製到映象中,
                          ADD 原始檔位置   目的檔案位置
                              原始檔位置,可以時構建目錄下的檔案,也可以時網路檔案
                          eg:
                             將構建目錄下的software.lic 複製到  映象中 /opt/application/software.lic 
                             ADD software.lic /opt/application/software.lic 
                          注意:
                             ADD 再處理壓縮檔案(gzip,bzip2,gz)時,會自動解壓
                             eg:
                               ADD latest.tar.gz /var/www/wordpress/
                               將歸檔檔案latest.tar.gz解壓到/var/www/wordpress/目錄下
                           
                  COPY
                          類似ADD, 
                             COPY  只關心在構建上下文中複製本地檔案,而不去做檔案提取和解壓的工作
                                   只能複製當前構建目錄中的檔案或目錄
                             eg:
                                把本地conf.d目錄中的檔案複製到/etc/apache2/目錄中
                                COPY conf.d/ /etc/apache2/
                                
                  
                 VOLUME
                          用來向基於映象建立的容器添加捲
                          卷 可在容器間共享和重用
                          對卷的修改時立時生效的,對卷的修改不會對更新映象產生影響
                          卷會一直存在,直到沒有任何容器再使用它
                          -v 引數 覆蓋添加捲
                          eg:
                             通過陣列方式指定多個卷,為基於此映象的任何容器建立一個名為 /opt/project 和 /data的掛載點
                             VOLUME ["/opt/project", "/data"]
                          
                 WORKDIR
                          用來在從映象建立一個新容器時,在容器內部設定一個工作目錄, ENTRYPONT、CMD指定的程式會在這個目錄下執行
                          eg:
                             WORKDIR /opt/webapp/db
                             RUN bundle install
                             WORKDIR /opt/webapp
                             ENTRYPOINT ["rackup"]
                          解析:
                             工作目錄切換為 /opt/webapp/db後執行bundle install 命令, 
                             之後又將工作目錄設定為 /opt/webapp,最後設定ENTRYPOINT指令來啟動rackup命令
                          注意:
                             啟動容器時,通過 -w 覆蓋工作目錄
                             eg:
                                將容器內的工作目錄設定為 /var/log
                                dockker run -ti -w /var/log ubuntu pwd
                                
                  
                 USER
                        指定該映象會以什麼樣使用者執行
                        eg:
                           USER nginx       基於該映象啟動的容器會以nginx使用者的身份執行,如果不設定,預設使用者是root
                           docker run命令中  -u 引數,覆蓋指定的值
                  
                 ONBUILD
                  
                        為映象新增觸發器,當一個映象被用作其他映象的基礎映象時,該映象中的觸發器將會被執行.
                        觸發器會在構建過程中插入新指令,可以認為這些指令時緊跟在FROM之後指定的,
                        觸發器可以時任何構建指令,
                        ONBUILD指令可以在映象上執行 docker inspect 命令檢視
                        eg:
                          ONBUILD ADD . /app/src
                          ONBUILD RUn cd /app/src && make
                        解析:
                          以此映象作為基礎進行時,會把當前目錄新增到 /app/src/目錄中,並在目標目錄中,執行make操作進行編譯 
                          類似redis原始碼編譯                         
                  
                 ENV
                        設定環境變數
                        這個新的環境變數可以在後續的任何RUN指令中使用,如同在命令前面指定了環境變數字首一樣
                        eg:
                          ENV TARGET_DIR /opt/app
                          WORKDIR $TARGET_DIR
                          
            7.將映象推送到Docker Hub
                  docker push static_web
                  
            8.執行自己的 Docker  Registry    ---  自定義倉庫,類似 maven私服
                  1.拉取Docker Registry 映象
                    docker pull registry
                  2.從容器執行Registry
                    啟動一個執行Registry的容器,並繫結到宿主機的5000埠
                    docker run -p 5000:5000 registry
                  3.推送映象到自己的Registry 
                    docker push IP:5000/author/image_name:tag
                    eg:
                       docker push 127.0.0.1:5000/jayhe/jdk8_tomcat8
                    注意:一般先為要推送的映象打tag,然後在推送到Registry
                        1.打tag
                           docker tag 映象id 映象名:tag
                           docker tag 2hkjh3f jayhe/jdk8_tomcat8:v2
                        2.推送到Registry
                           docker push IP:5000/映象名
                           docker push 127.0.0.1:5000/jayhe/jdk8_tomcat8
                           
                           
3.使用Docker
    本地開發和測試:
   使用Docker測試一個靜態網站
     1.建立目錄
       mkdir static_web
       cd static_web
     2.下載2個配置檔案
       global.conf
       wget https://raw.githubusercontent.com/jamtur01/dockerbook-code/master/code/5/sample/nginx/global.conf
       內容:
           server {
       listen          0.0.0.0:80;
       server_name     _;

       root            /var/www/html/website;
       index           index.html index.htm;

       access_log      /var/log/nginx/default_access.log;
       error_log       /var/log/nginx/default_error.log;
}
           
           配置解析:
                  將Nginx設定為監聽80埠,並將網路服務的根路徑設定為 /var/www/html/website
           
       nginx.conf
       wget https://raw.githubusercontent.com/jamtur01/dockerbook-code/master/code/5/sample/nginx/nginx.conf
       內容:
           user www-data;
worker_processes 4;
pid /run/nginx.pid;
daemon off;

events {  }

http {
 sendfile on;
 tcp_nopush on;
 tcp_nodelay on;
 keepalive_timeout 65;
 types_hash_max_size 2048;
 include /etc/nginx/mime.types;
 default_type application/octet-stream;
 access_log /var/log/nginx/access.log;
 error_log /var/log/nginx/error.log;
 gzip on;
 gzip_disable "msie6";
 include /etc/nginx/conf.d/*.conf;
}
           
           配置解析:
                  將Nginx配置為非守護程序模式,配置Nginx
       
     
     3.建立Dockerfile,新增以下內容:
       方式1:基於基礎映象Nginx建立 
           #Version: 0.0.1
FROM nginx 
MAINTAINER Jay He [email protected]
RUN mkdir -p /var/www/html
#刪除nginx中的預設配置
RUN rm /etc/nginx/conf.d/default.conf
ADD global.conf /etc/nginx/conf.d/
ADD nginx.conf /etc/nginx/nginx.conf
EXPOSE 80




           
       方式2:基於基礎映象ubuntu14.04建立
       #Version: 0.0.1
FROM ubuntu:14.04
MAINTAINER Jay He [email protected]
RUN apt-get update
RUN apt-get -y -q install nginx
RUN mkdir -p /var/www/html
ADD global.conf /etc/nginx/conf.d/
ADD nginx.conf /etc/nginx/nginx.conf
EXPOSE 80

Dockerfile解析:
   1.安裝nginx
   2.在容器中建立目錄 /var/www/html
   3.將下載的2個nginx配置檔案新增到映象中
           4.公開映象的80埠    
           
 4.建立映象
   docker build -t="jay/nginx:v1" .
   
 5.從Sample網站和剛建立的jay/nginx:v1映象構建容器          
       1.建立目錄
       mkdir sample 
       cd sample
       mkdir website && cd website
       2.獲取檔案,放到website目錄中
           wget https://raw.githubusercontent.com/jamtur01/dockerbook-code/master/code/5/sample/website/index.html
       3.建立容器
           在website路徑中,執行建立容器命令:
           docker run -d -p 8080:80 --name website -v $PWD/sample:/var/www/html/website jay/nginx:v1 nginx
           注意:
              1.當前路徑  /home/jayhe/jay/docker/my_images/static_web
                        路徑下sample目錄中存放index.html
              2. -v target:destination 命令  掛載 宿主機target捲到容器的destination卷   
                 即:
                    宿主與容器共享檔案(目錄)
                    target下的檔案,可以通過destination進行訪問,這裡 sample/index.html 與容器的/var/www/html/website/index.html是同一個
              
       4.進入已建立的容器,檢視目錄
           這裡 1ce51 是執行的容器id
           docker exec -it 1ce51 /bin/bash        
           進入共享卷,共享目錄 /var/www/html/website 與 宿主 $PWD/sample目錄相同
           cd /var/www/html/website 
       
       5.修改網站內容   ---  修改宿主與容器共享卷裡面的內容即可
           eg:
             修改 /home/jayhe/jay/docker/my_images/static_web/sample目錄下的index.html,
             容器中/var/www/html/website目錄下的index.html隨之變化,
             localhost:8080 訪問nginx即可看到變化
              
       特別注意:
            1.在建立的Nginx容器中,將卷(指定目錄) $PWD/sample 掛載到容器的 /var/www/html/website/目錄
            2.在nginx配置檔案(/etc/nginx/conf.d/global.conf)中,指定了掛載後的目錄 /var/www/html/website/ 作為Nginx伺服器的工作目錄
              注意:
                  如果時基於nginx建立的映象,nginx基礎映象預設會將 /etc/nginx/conf.d/default.conf作為配置檔案,
                  自定義的映象,可以刪除該預設配置,替換成自己的配置檔案即可(方式1:建立nginx映象)
                  
       
   使用Docker建立並測試一個Web應用 
       容器互聯:
              流程:引用容器名字
          1.啟動一個redis容器
                docker run -d -p 6789:6379 --name redis_test1 redis
          2.本地連線redis容器
                #進入宿主機redis目錄
                cd /home/jayhe/jay/soft/redis/redis-3.2.0/src
                #通過宿主機redis客戶端連線redis容器
                ./redis-cli -h 127.0.0.1 -p 6789
              
              3.通過引用容器名字,實現兩個容器的互聯
                    --link 要連線的容器名   連線後容器的別名                     
                     
                    docker run -p 4567:8080 --name webapp1 --link redis:redis_test1 -it -v $PWD/webapp:/opt/webapp jay/webapp:v1 /bin/bash
                    解析:
                        1.啟動一個基於jay/webapp映象的容器,對映容器埠8080到宿主機埠4567   
                             2.將容器redis_test連線到容器webapp1,並使用db作為其別名
                             3.將 $PWD/webapp掛載到容器/opt/webapp
                         說明:
                             1.--link arg1:arg2 標誌建立2個容器間的父子連線,
                                  arg1:  要連線的容器名字
                                  arg2:  連線後容器的別名,別名可以讓我們訪問公開的資訊,而無須關注底層容器的名字
                                  連線讓父容器可以訪問子容器,並把子容器的一些連線細節分享給父容器,而不是公開
                                  eg:
                                     把新容器連線到redis容器,並使用db作為redis容器別名
                                     --link redis:db  
                            注意:
                                1.啟動redis容器時,並不需要用 -p 公開redis的埠,通過容器連線,可以讓父容器直接訪問任意子容器的公開埠
                                 (eg:父容器webapp可以連線到子容器redis的6739埠)
                                2.只有使用--link標誌連線到這個容器才能連線到這個埠,容器的埠不需要對本宿主機公開,保證了容器訪問的安全
                                3.可以把多個容器連線在一起,如果想讓多個web程式連線到redis例項,則可以把多個web應用和同一個redis容器連線到一起
                             docker run -p 4567:8080 --name webapp1 --link redis:db ....
                             docker run -p 4568:8080 --name webapp2 --link redis:db ....
                             docker run -p 4569:8080 --name webapp3 --link redis:db ....
                             注意:
                                 被連線的容器必須執行在同一個Docker宿主機上,不同的宿主機上執行的容器無法連線!!!
                           4.Docker父容器裡的2個地方寫入了連線資訊
                                 1. /etc/hosts檔案中
                                 2. 包含連線資訊的環境變數中
                                 eg1:
                                    進入父容器,檢視 /etc/hosts檔案
                                    root@8fd812gd:/# cat /etc/hosts
                                    172.17.0.71 8fd812gd
                                    ...
                                    172.17.0.67 db
                                 解析:
                                    1.  第一行:容器自己的IP地址和主機名(住寂寞時容器ID的一部分)
                                   最後一行:由該連線建立的,它時redis容器的IP地址賀從該連線的別名衍生的主機名db
                                    2.在父容器中 ping db 可以檢視被連線容器ip
                                    3.為容器設定主機名
                                      docker run 命令使用 -h 或 --hostname 來為容器設定主機名   
                                 eg2:
                                        父容器中執行env命令檢視環境變數,也可檢視容器連線資訊
               
               4.使用容器連線來通訊    
                  
    
    Docker用於構建和測試
     將Docker用於持續整合         
      1.使用Dokcer hub的官方Jenkins映象  
       1.基於jenkins映象建立容器   --- 建立後臺執行的jenkins容器
         docker run -p 8080:8080 --name jenkins -d jenkins
       2.進入建立的容器  87b9 是jenkins容器的id
         docker exec -it 87b9 /bin/bash
       3.獲取初始密碼,在訪問時需要使用
         jenkins@87b958faabb3:/$ cd /var/jenkins_home/secrets/ 
         jenkins@87b958faabb3:/$ cat initialAdminPassword
         得到jenkins的初始密碼
       4.訪問jenkins
         localhost:8080, 輸入出初始化密碼,裝外掛,設定使用者,開始使用Jenkins
      
     2.自定義Jenkins映象    ---  基於自定義的Dockerfile建立自己的jenkins映象,使用方法與上面一樣






3.使用Dokcer構建服務
      1.構建應用    Jekyll映象 + Apache映象 + github 實現部落格
         2個映象:
                jekyll映象和Apache映象
         2個容器:
       從Jekyll映象建立容器,這個容器存放通過卷掛載的網站原始碼
       從Apache映象建立容器,這個容器利用包含編譯後的網站的卷,併為其服務
1.拉取2個映象
       docker pull eboraas/apache
       docker pull jekyll/jekyll
2.建立2個容器   
       1.建立jekyll容器,並掛載卷, 利用卷可以在容器間共享資料     
         docker run -v /home/jayhe/jay/docker/my_images/jay_jekyll/jay/james_blog:/data/ --name jay_blog jekyll/jekyll
           Configuration file: /srv/jekyll/_config.yml
           Source: /srv/jekyll
      Destination: /srv/jekyll/_site
Incremental build: disabled. Enable with --incremental
     Generating... 
                   done in 0.149 seconds.
Auto-regeneration: enabled for '/srv/jekyll'
Configuration file: /srv/jekyll/_config.yml
   Server address: http://0.0.0.0:4000/
 Server running... press ctrl-c to stop.
            
         解析:
            啟動一個容器blog,把本地james_blog目錄作為 /data/卷掛載到該容器中,
            容器拿到網站原始碼,並將其構建到已編譯的網站,存放到 /srv/jekyll/_site 目錄
       
       2.建立Apache容器
         docker run -d -p 8080:80 -v /home/jayhe/jay/docker/my_images/jay_jekyll/jay/james_blog/_site:/var/www/html eboraas/apache
         解析:
             -v /home/jayhe/jay/docker/my_images/jay_jekyll/jay/james_blog/_site:/var/www/html  
             解析:
                1.將生成的網站目錄 _site 共享到Apache容器的 /var/www/html目錄
                2./var/www/html 是Apache容器的工作目錄,放到這裡的內容才能被apache解析
                3.通過 localhost:8080 訪問apache服務, 可以看到_site中的內容

基於Docker MySQL的主從複製

4.Docker MySQL 實現主從複製(1 Master + 2 Slave)
  1.要求:
      3個mysql版本一致
      初始化表,並在後臺啟動mysql
      修改root密碼
      
      
  修改配置檔案:
           啟動一個docker mysql 容器,並進入,複製其配置檔案 /etc/mysql/my.cnf到本地,作為基礎配配置
           >docker run --name db1 -p 30000:3306 -d -e MYSQL_ROOT_PASSWORD='root' mysql:5.6
            757b456814f4c13ae9559e3723ad5025f2e787fb003a1b7e32f675e4874d5f50
            docker exec -it 757b /bin/bash
            cat /etc/mysql/my.cnf
            拷貝內容到 /home/jayhe/jay/config/mysql/master_2slave/my-m.cnf 作為基礎配置,下面的修改都是基於這個基礎配置
            
            
  2.修改主伺服器master:
      my.cnf
         [mysqld]
         #[必須]啟動二進位制日誌
         log-bin=mysql-bin
         #[必須]設定伺服器唯一ID,預設時1,一般取IP最後一段
         server-id=3001 
  3.修改從伺服器slave:
      my.cnf
         [mysqld]
         #[非必須]啟動二進位制日誌
         log-bin=mysql-bin
         #[必須]設定伺服器唯一ID,預設時1,一般取IP最後一段
         server-id=3002
      
      my.cnf
         [mysqld]
         #[非必須]啟動二進位制日誌
         log-bin=mysql-bin
         #[必須]設定伺服器唯一ID,預設時1,一般取IP最後一段
         server-id=3003
       
  啟動3個mysql:
         主伺服器:掛載   /xx/xx/my.cnf(主伺服器配置)到mysql容器
             docker run --name mysql1 -p 3001:3306 -d -v /home/jayhe/jay/config/mysql/master_2slave/my-m.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD='root' mysql:5.6
         從伺服器:掛載   /xx/xx/my.cnf(從伺服器配置)到mysql容器
             docker run --name mysql2 -p 3002:3306 -d -v /home/jayhe/jay/config/mysql/master_2slave/my-s1.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD='root' mysql:5.6
             docker run --name mysql3 -p 3003:3306 -d -v /home/jayhe/jay/config/mysql/master_2slave/my-s2.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD='root' mysql:5.6
 
  連線容器中的mysql   ---  即使本地mysql每啟動,仍然可以連線容器的mysql服務
         語法:
             mysql -h IP -P port -uroot -proot
         
         連線主伺服器
         mysql -h 127.0.0.1 -P 3001 -uroot -proot     
         登入主伺服器,建立賬戶並授權
         grant replication slave on *.* to 'mysync'@'%' identified by 'root';
         檢視主伺服器狀態
         show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000004 |      312 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
        
         
         登入從伺服器:
         mysql -h 127.0.0.1 -P 3002 -uroot -proot
         
         配置從伺服器:  
                    ---  這裡的 master_log_file='mysql-bin.000004', master_log_pos與主伺服器中的master status一致
         change master to master_host='172.17.64.106',master_port=3001,master_user='mysync',master_password='root',master_log_file='mysql-bin.000004', master_log_pos=312;
 
        啟動從伺服器複製功能
         start slave;
                 
        檢視從伺服器複製功能狀態:
         show slave status;
        +----------------------------------+---------------+-------------+-------------+---------------+------------------+---------------------+-------------------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+----------------------------+-----------+---------------------+-----------------------------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+
| Slave_IO_State                   | Master_Host   | Master_User | Master_Port | Connect_Retry | Master_Log_File  | Read_Master_Log_Pos | Relay_Log_File          | Relay_Log_Pos | Relay_Master_Log_File | Slave_IO_Running | Slave_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Master_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Master_SSL_Allowed | Master_SSL_CA_File | Master_SSL_CA_Path | Master_SSL_Cert | Master_SSL_Cipher | Master_SSL_Key | Seconds_Behind_Master | Master_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Master_Server_Id | Master_UUID                          | Master_Info_File           | SQL_Delay | SQL_Remaining_Delay | Slave_SQL_Running_State                                                     | Master_Retry_Count | Master_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Master_SSL_Crl | Master_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position |
+----------------------------------+---------------+-------------+-------------+---------------+------------------+---------------------+-------------------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+----------------------------+-----------+---------------------+-----------------------------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+
| Waiting for master to send event | 172.17.64.106 | mysync      |        3001 |            60 | mysql-bin.000004 |                 409 | mysqld-relay-bin.000002 |           380 | mysql-bin.000004      | Yes              | Yes               |                 |                     |                    |                        |                         |                             |          0 |            |            0 |                 409 |             554 | None            |                |             0 | No                 |                    |                    |                 |                   |                |                     0 | No                            |             0 |               |              0 |                |                             |             3001 | 735f9147-d3ec-11e6-b8c6-0242ac120002 | /var/lib/mysql/master.info |         0 |                NULL | Slave has read all relay log; waiting for the slave I/O thread to update it |              86400 |             |                         |                          |                |                    |                    |                   |             0 |
+----------------------------------+---------------+-------------+-------------+---------------+------------------+---------------------+-------------------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+----------------------------+-----------+---------------------+-----------------------------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+
注意:
   Slave_IO_State  =  Waiting for master to send event
   Slave_IO和Slave_SQL 都是 YES
   則表示主從複製配置成功

   測試主從複製:
        進入主伺服器,建立一個數據庫
       mysql -h 127.0.0.1 -P 3001 -uroot -proot
       create database test1;
        進入從伺服器,檢視資料庫,發現已經存在了test1   --- 與主伺服器同步
            mysql -h 127.0.0.1 -P 3001 -uroot -proot
            mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test1              |
+--------------------+
            
            
     特別注意:
      1.主伺服器中,建立賬戶並授權
          grant replication slave on *.* to 'mysync'@'%' identified by 'root';
          一般不用root賬戶,
          *.* 表示所有客戶端都可連,只要賬戶和密碼正確,這裡可用具體IP代替,加強安全 eg: 192.168.145.222
          
      2.從伺服器中,配置從伺服器時:
          master_host 為docker的宿主機地址,    不能寫  127.0.0.1
          master_port 為主伺服器mysql對映到宿主機的埠  3001
          master_user 為主伺服器中建立的使用者            mysync
          master_log_file 為主伺服器show master status查詢出來的 File
          master_log_pos 為主伺服器show master status查詢出來的 Position      
               
               3.配置檔案其他內容配置項:
                    #如果需要增加Slave庫則,此id往後順延;  
server-id = 2    
log-bin=mysql-bin  
#主庫host  
master-host = 192.168.168.253  
#在主資料庫伺服器中建立的用於該從伺服器備份使用的使用者  
master-user = forslave  
master-password = ******  
master-port = 3306  
#如果發現主伺服器斷線,重新連線的時間差;  
master-connect-retry=60  
#不需要備份的資料庫;   
replicate-ignore-db=mysql  
#需要備份的資料庫  
replicate-do-db=minishop  
log-slave-update 
         
            

          4.從MySQL映象容器中獲取的 my.cnf 基礎配置 

# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA

#
# The MySQL Community Server configuration file.
#
# For explanations see
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html

[client]
port		= 3306
socket		= /var/run/mysqld/mysqld.sock

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

[mysqld]
user		= mysql
pid-file	= /var/run/mysqld/mysqld.pid
socket		= /var/run/mysqld/mysqld.sock
port		= 3306
basedir		= /usr
datadir		= /var/lib/mysql
tmpdir		= /tmp
lc-messages-dir	= /usr/share/mysql
explicit_defaults_for_timestamp
log-bin=mysql-bin
server-id=3001
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
#bind-address	= 127.0.0.1

#log-error	= /var/log/mysql/error.log

# Recommended in standard MySQL setup
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

# * IMPORTANT: Additional settings that can override those from this file!
#   The files must end with '.cnf', otherwise they'll be ignored.
#
!includedir /etc/mysql/conf.d/