docker學習筆記(一)

   docker是一種容器技術,如今火的一塌糊塗,最近公司打算用docker統一開發、測試、預上線、上線環境,因此花了時間研究一下。
    docker是一種容器技術,以前是基於LXC容器,如今已經改爲基於libcontainer了。研究了幾天,對docker有如下總結:
    1)docker是一種容器技術,容器中包含了一個微型操做系統,咱們在容器中封裝咱們要運行的程序環境,這樣就節省了環境配置和維護的時間和人力成本,容器有本身的網絡環境,能夠定製其使用的cpu、內存和磁盤等資源,對於運維來講,尤爲是對於頻繁發佈的運維人員來講,是個福音。聽說亞馬遜天天要發佈上萬次、谷歌也有幾千次,其發佈間隔已經到分鐘級。固然這種發佈,不只僅是docker的做用,其餘一系列的自動化配置、自動化測試、自動化發佈、自動化回滾都要跟上才行。
    2)docker的性能要低於裸機,因此在小型系統的運行環境中沒有必要使用docker
    3)docker的穩定性須要注意,在上線以前須要進行充分的壓力測試
    4)docker是基於linux的,因此windows和Mac都使用virtualBox虛擬機來實現的。
    5)docker能夠很快的搭建測試環境,可是對於開發環境來講,由於是另一臺機器,因此調試、自動完成、代碼提示都會有必定的問題,須要特殊的配置。
    6)docker不是虛擬機,是一個容器,更準確的來講,是一個程序,因此啓動容器須要指定啓動程序,不然容器會啓動失敗,另外雖然容器是個微型操做系統,可是沒有服務自動運行的概念,這一點對於有必定運維經驗的同窗來講容易混淆。
    7)容器的構建通常基於ubuntu、debian、centos等linux發行版,因此若是想構建本身的docker鏡像,最好同時安裝對應的虛擬機,測試一些命令,運行成功了,再放到Dockerfile中,不然會比較麻煩。
    8)構建容器有兩種辦法,一種是在現有鏡像的基礎上,登陸容器,更新容器,讓後將容器內容保存爲鏡像,這種方法通常是初學者用來學習測試用,另一種是經常使用的Dockerfile,這個文件規定了容器構建的步驟和命令,能夠重複運行,並能夠根據本身的要求本身修改,獲得新的鏡像。
    9)鏡像的得到:最權威的是hub.docker.com,能夠在上面搜索到相應的須要的鏡像,根聽說明文檔拉取鏡像到本地就能夠了,不過速度要慢一些,國內一些公司作了hub.docker.com的備份,能夠從國內拉取鏡像,速度要快的多,這種公司也很多,daoclound和靈雀雲能夠嘗試一下
   10)能夠創建本身的私有鏡像中心,docker公司提供了一個docker-registry的鏡像,能夠直接使用,啓動以後,就有了一個本身的鏡像中心,在上面能夠進行發佈和拉取鏡像的操做,這也算一個快速部署的例子吧,固然也能夠在其基礎上作定製。
   11)docker容器是不會保存文件的,若是容器中止,容器裏所做的修改就不存在了,因此容器中須要保存的部分須要放在容器外,能夠將宿主機的目錄和文件,映射到容器內部,映射以後,若是容器內存在該文件或目錄,會覆蓋容器內的文件;還能夠不指定宿主的目錄文件,宿主機會自動生成一個文件,目錄文件名是隨機的。
   12)docker容器自己有本身的ip地址,當docker啓動時,默認會建立一個docker0網橋,本機的容器都會從這個網橋獲得一個地址,並與之互通,這個地址能夠經過docker inspect命令看到,在本機能夠直接用ip地址訪問。可是其餘機器就訪問不了了。這個問題的解決方法不少,有的複雜,有的簡單,最簡單的方法是將容器的對外訪問的端口暴露出來,映射到宿主機的端口,這樣其餘機器就能夠訪問了。若是容器之間須要訪問,由於其ip地址是不肯定的,因此須要用容器鏈接來解決,容器鏈接本質上是將容器名稱和容器IP關聯起來,修改父容器的/etc/hosts,因此忽略IP鏈接問題。固然還有更復雜的,就是不創建docker0網橋,直接分配docker容器地址,配置路由,這個比較麻煩,須要研究一下iptables命令,不過有一些工具能夠用來解決這個問題,這也是docker集羣大規模部署的基礎。感興趣能夠研究一下weave,kubernetes
   爲方便起見,在linux虛擬機中作docker的實驗,環境以下
   操做系統:CentOS 7 
   內存: 3.2G
   CPU核數 : 2
   實驗內容:搭建ngixn 1.9 + php-fpm 5.6 + mysql 5.6
   IP:172.16.10.138
   步驟以下:
   1)安裝docker,根據官方網站的步驟
        a) 更新軟件包
            $ yum upate
        b) 更新yum資源庫
            $ tee /etc/yum.repos.d/docker.repo <<-'EOF'
            [dockerrepo]
            name=Docker Repository
            baseurl=https://yum.dockerproject.org/repo/main/centos/$releasever/
            enabled=1
            gpgcheck=1
            gpgkey=https://yum.dockerproject.org/gpg
            EOF
  c)安裝docker
      $ yum install docker-engine
            $ systemctl start docker
            $ systemctl enable docker
            須要啓動docker服務才能夠,不然docker沒法使用,上面將docker服務設置爲自動啓動
       d)docker命令簡介
            docker的啓動和運行命令都是docker,docker --help能夠看到全部的詳細參數內容,常見的有如下內容
            docker build 構建鏡像,使用Dockerfile
            docker run 運行容器
            docker pull 拉取鏡像
            docker push 推送鏡像
            docker attach 鏈接到已經運行的容器上
            docker restart 從新啓動容器
            docker rmi 刪除鏡像
            docker rm 刪除容器
            docker stop 中止容器
            docker start 啓動容器
            docker save 保存鏡像到tar文件,包括歷史
            docker load 恢復tar文件到鏡像,save的反命令
            docker export 導出鏡像最新文件系統到tar文件,沒有歷史,大小要小於save命令
            docker import 導入tar文件生成鏡像,export的反命令
            docker images 顯示全部鏡像
            docker inspect 顯示容器信息
            docker ps 顯示運行的容器信息
            docker ps -l 顯示最後的容器信息,即便已經中止
 2)配置和目錄結構:/root/Dockerfiles下
      ├── mysql
      │   └── Dockerfile
      ├── nginx
      │   ├── default.conf
      │   └── Dockerfile
      └── php
           └── Dockerfile
      mysql基本就是從網上下載的鏡像,nginx須要修改配置文件,因此增長了一個default.conf,用來覆蓋容器內的配置文件,php容器的配置文件比較簡單,不作修改
      /data/html目錄保存html和php文件,保存在容器外,這個目錄須要映射到nginx和php容器,也定爲/data/html
      
      在/data/html下寫入三個文件, index.htm info.php mysql.php,分別測試靜態文件、PHP文件、Mysql鏈接
     $ echo '<h1>Hello World!</h1>' > /data/html/index.htm
     $ echo '<?php' > /data/html/info.php
     $ echo '   phpinfo();' >> /data/html/info.php
     $ vim mysql.php
     <?php
     $con = mysql_connect("mysql", "root", "123456");
     if (!$con)
     {
       die('Could not connect: ' . mysql_error());
      }
     $db_selected = mysql_select_db("shiyq",$con);
     mysql_query("set names utf8");
     $sql = "SELECT * from t";
     $result = mysql_query($sql,$con);
     while($row = mysql_fetch_array($result)){
       print_r($row);
     }
     mysql_close($con);
     
     三個容器命名分別爲mysql、pfpm、nginx,便於容器鏈接
 3)mysql, mysql目錄下
     $vim Dockerfile
      FROM mysql:5.6
     $docker build -t shiyq/mysql:5.6 .
     Sending build context to Docker daemon 2.048 kB
     Step 1 : FROM mysql:5.6
     5.6: Pulling from library/mysql
     7268d8f794c4: Pull complete
     a3ed95caeb02: Pull complete
     e5a99361f38c: Pull complete
     50aeb59ed433: Pull complete
     5bedb4177480: Pull complete
     366f809ce7dd: Pull complete
     9d8799acdbcd: Pull complete
     647411343675: Pull complete
     a18cdc480897: Pull complete
     45d42e99e3be: Pull complete
     Digest: sha256:8f7fd54e7253031030d060925e4abb78f8387b7417e3afd4b7fde6551cc50255
     Status: Downloaded newer image for mysql:5.6
     ---> f0e9d0beeb6b
     Successfully built f0e9d0beeb6b
     mysql:5.6鏡像的Dockerfile能夠在https://github.com/docker-library/mysql/blob/ace4c65b8e97f0145616386916aabaec518d4e08/5.6/Dockerfile查看
     $docker images
     REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
     mysql               5.6                 f0e9d0beeb6b        26 hours ago        324.2 MB
     shiyq/mysql         5.6                 f0e9d0beeb6b        26 hours ago        324.2 MB
     能夠看出有兩個鏡像,大小是同樣的,緣由是我建立的鏡像其實就是徹底的複製官方鏡像。

經過Dockerfile能夠看出,官方鏡像已經用VOLUME指令將mysql數據目錄放到了容器外,當容器運行會產生一個隨機目錄,這個目錄能夠經過docker inspect看到,不過老是不舒服,這裏指定/root/opt/mysql/data來存放數據,即將其映射到/var/lib/mysql,所以,啓動容器命令以下php

     $ docker run -it -e MYSQL_ROOT_PASSWORD=123456 -v /root/opt/mysql/data:/var/lib/mysql shiyq/mysql:5.6
     -it表明是交互模式,能夠看到輸出,主要用於測試,若是正式發佈,能夠用-d,即後臺運行
     -e是環境變量,這個容器啓動須要設置root密碼,這裏設置爲123456
     -v是目錄映射,將本地的/root/opt/mysql/data映射爲/var/lib/mysql
     $docker ps
     CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES
     e5c92a9be37c        shiyq/mysql:5.6     "/entrypoint.sh mysql"   4 minutes ago       Up 4 minutes        3306/tcp            modest_jennings
     $ docker inspect e5c92a9be37c        
     這能夠看到不少信息,好比ip地址、環境變量、目錄映射等,這裏的ip地址是172.17.0.2,在宿主機上運行mysql命令
     $ mysql -uroot -p123456 -h 172.17.0.2 -P 3306
     就能夠登陸進去了,和正常的mysql數據庫沒有區別。
     不過這樣操做很不方便,須要知道容器的ip地址才能操做,能夠將3306端口映射到本地端口,如3307,再次啓動容器
    $ docker stop e5c92a9be37c        
    $ docker run -it --name mysql -e MYSQL_ROOT_PASSWORD=123456 -p 3307:3306 -v /root/opt/mysql/data:/var/lib/mysql shiyq/mysql:5.6
    $ mysql -uroot -p123456 -h 127.0.0.1 -P 3307
    mysql> create database shiyq default character set utf8;
    mysql> use shiyq;
    mysql> create table t(id int not null auto_increment primary key,name varchar(20),code varchar(20));
    mysql> insert into t(name,code) values('石永強','shiyq');
4)php-fpm,php目錄下
    $ vim Dockerfile
    FROM debian:jessie
    RUN apt-get update
    RUN apt-get install -y php5-fpm php5-mysql php5-mysqlnd
    RUN sed -i "s/^listen = .*$/listen = 9000/g" /etc/php5/fpm/pool.d/www.conf
    RUN sed -i "s/;daemonize = yes/daemonize = no/g" /etc/php5/fpm/php-fpm.conf
    RUN echo "#!/bin/bash" > /root/run.sh
    RUN echo "/usr/sbin/php5-fpm" >> /root/run.sh
    RUN chmod u+x /root/run.sh
    EXPOSE 9000
    CMD ["/root/run.sh"]
    這個Dockerfile是自定義的,採用了debian 8,同時修改了默認的配置文件,將監聽設置從unix socket改成端口9000,並禁止其後臺運行。
    $ docker build -t shiyq/php-c:5.6-fpm .     
    $ docker run -it --name pfpm --link mysql -p 9001:9000 -v /data/html:/data/html shiyq/php-c:5.6-fpm 
    題外話:官方鏡像沒法使用,不能訪問Mysql,因此只好自定義
5)nginx, nginx目錄下
    $ vim Dockerfile
     FROM nginx:1.9
     $ docker build -t shiyq/nginx:1.9 .
     Sending build context to Docker daemon  2.56 kB
     Step 1 : FROM nginx:1.9
     1.9: Pulling from library/nginx
     7268d8f794c4: Already exists
     a3ed95caeb02: Pull complete
     455603953088: Pull complete
     7648078317e7: Pull complete
     Digest: sha256:3feee5ea8dd682950c9873e8c1d9d689b7d257f1ee8f82a11c484cee9dd6c446
     Status: Downloaded newer image for nginx:1.9
      ---> 574907042fd7
     Successfully built 574907042fd7
     $ docker run -it shiyq/nginx:1.9 /bin/bash
     root@1ffba22d4129:/# cat /etc/nginx/conf.d/default.conf
     server {
         listen       80;
         server_name  localhost;
         #charset koi8-r;
         #access_log  /var/log/nginx/log/host.access.log  main;
         location / {
             root   /usr/share/nginx/html;
             index  index.html index.htm;
         }
         #error_page  404              /404.html;
         # redirect server error pages to the static page /50x.html          #
         error_page   500 502 503 504  /50x.html;
         location = /50x.html {
             root   /usr/share/nginx/html;
         }
         # proxy the PHP scripts to Apache listening on 127.0.0.1:80
         #
         #location ~ \.php$ {
         #    proxy_pass   http://127.0.0.1;
         #}
         # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
         #
         #location ~ \.php$ {
         #    root           html;
         #    fastcgi_pass   127.0.0.1:9000;
         #    fastcgi_index  index.php;
         #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
         #    include        fastcgi_params;
         #}
         # deny access to .htaccess files, if Apache's document root
         # concurs with nginx's one
         #
         #location ~ /\.ht {
         #    deny  all;
         #}
     }
     將容器的default.conf的內容複製到本地的default.conf,並修改以下
     server {
         listen       80;
         server_name  localhost;
         #charset koi8-r;
         #access_log  /var/log/nginx/log/host.access.log  main;
         location / {
             root   /data/html;
             index  index.html index.htm index.php;
         }
         #error_page  404              /404.html;
         # redirect server error pages to the static page /50x.html
         #
         error_page   500 502 503 504  /50x.html;
         location = /50x.html {
             root   /data/html;
         }
         # proxy the PHP scripts to Apache listening on 127.0.0.1:80
         #
         #location ~ \.php$ {
         #    proxy_pass   http://127.0.0.1;
         #}
         # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
         #
         location ~ \.php$ {
              root           /data/html;
              fastcgi_pass   pfpm:9000;
              fastcgi_index  index.php;
              fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
              include        fastcgi_params;
         }
         # deny access to .htaccess files, if Apache's document root
         # concurs with nginx's one
         #
         #location ~ /\.ht {
         #    deny  all;
         #}
     }
     增長和修改的內容已經黑體標出,主要是修改了默認的目錄爲/data/html,另外打開了php-fpm,用來運行php程序,不過須要注意的是這裏的主機名用的pfpm,這是php-fpm容器使用的名字,最後會採用容器鏈接的方式鏈接php-fpm,一樣php-fpm也會用一樣的方式鏈接mysql容器。

 

     $  docker run -it --name nginx --link pfpm -p 800:80 -v /data/html:/data/html -v /root/Dockerfiles/nginx/default.conf:/etc/nginx/conf.d/default.conf shiyq/nginx:1.9
 6)運行
     $ docker ps
     CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                            NAMES
     e33a1cc68794        shiyq/nginx:1.9     "nginx -g 'daemon off"   2 minutes ago       Up 2 minutes        443/tcp, 0.0.0.0:800->80/tcp   nginx
     40c3ac953494        shiyq/php:5.6-fpm   "php-fpm"                4 minutes ago       Up 4 minutes        0.0.0.0:9001->9000/tcp         pfpm
     3228d0f7ce7e        shiyq/mysql:5.6     "/entrypoint.sh mysql"   12 minutes ago      Up 12 minutes       0.0.0.0:3307->3306/tcp         mysql
     能夠看到啓動了3個容器,nginx80端口映射爲宿主機800,鏈接到php容器,php-fpm的9000端口映射爲9001端口,鏈接到mysql容器,mysql容器的3306映射爲3307端口
     $ curl localhost:800

Hello World!

     $ curl localhost:800/mysql.php
     Array
     (
          [0] => 1
          [id] => 1
          [1] => 石永強
          [name] => 石永強
          [2] => shiyq
          [code] => shiyq
      )
 7)腳本
     $ vim start_npm.sh
     docker rm -f $(docker ps -a -q -f name="mysql|pfpm|nginx");
     docker run -it -d --name mysql -e MYSQL_ROOT_PASSWORD=123456 -p 3307:3306 -v /root/opt/mysql/data:/var/lib/mysql shiyq/mysql:5.6;
     docker run -it -d --name pfpm --link mysql -p 9001:9000 -v /data/html:/data/html shiyq/php-c:5.6-fpm;
     docker run -it -d --name nginx --link pfpm -p 800:80 -v /data/html:/data/html -v /root/Dockerfiles/nginx/default.conf:/etc/nginx/conf.d/default.conf shiyq/nginx:1.9;
     $./start_npm.sh 能夠自動刪除容器,並重啓容器
8)和windows共享文件
     a)創建e:/data/html目錄
     b)虛擬機共享目錄: 虛擬機->控制->設置->共享文件夾,固定分配,選擇共享名稱爲data_html,自動加載和固定分配勾選
     c)安裝加強功能:虛擬機->設備->安裝加強功能,這會在虛擬機上掛載一個硬盤
        $ mkdir /mnt/cdrom
        $ mount -t auto -r /dev/cdrom /mnt/cdrom
        $ yum install bzip2 kernel-devel
        $ cd /mnt/cdrom
        $ ./VBoxLinuxAdditions.run
     d) 掛載到/data/html
        $  mount -t vboxsf data_html /data/html
        $ curl localhost:800
        Array
        (
           [0] => 1
           [id] => 1
           [1] => 石永強
           [name] => 石永強
           [2] => shiyq
           [code] => shiyq
         )
        
     e)自動掛載
     $ chmod +x /etc/rc.local
     $ echo 'mount -t vboxsf data_html /data/html' >> /etc/rc.local
     f)重啓機器,能夠看到目錄已經掛載,
     $ /root/Dockerfiles/start_npm.sh
     $ curl localhost:800
     Array
    (
        [0] => 1
        [id] => 1
        [1] => 石永強
        [name] => 石永強
        [2] => shiyq
        [code] => shiyq
    )
   Array
   (
       [0] => 2
       [id] => 2
       [1] => 劉萬斌
       [name] => 劉萬斌
       [2] => liuwb
       [code] => liuwb
    )
    到此就能夠和windows共享文件,在windows上開發,在docker中運行,若是用文本編輯器寫程序,基本就能夠了,可是用ide,就有些麻煩了,須要本機也安裝php,要求版本一致,並不容易,尤爲是windows上的php很難找到低版本的,不過好在能夠在提交測試前就能夠發現問題。
    未解決的問題
    1)網絡地址問題:手動配置和工具配置。
相關文章
相關標籤/搜索