使用dockerfile 部署lnmpr環境

該文章爲學習docker 筆記一

docker 簡介

Docker 是基於GO語言實現的開源容器項目,如今主流的Linux系統都支持Docker,Docker 的構想是想要實現「Build,Ship and Run Any App, Anywhere」,即經過對應用的封裝(Packaging)、分發(Distribution)、部署(Deployment)、運行(Runtime)生命週期進行管理,達到應用組件「一次封裝,處處運行」的目的。
簡單的來講,能夠將Docker容器理解爲一種輕量級的沙盒(sandbox).每一個容器運行着一個應用,不一樣的容器相互隔離,容器之間也能夠經過網絡互相通訊。且容器的建立和中止都十分快速,幾乎跟建立和終止原生應用一致。php

爲何使用docker

  1. 加速本地的開發和構建流程,容器能夠在開發環境構建,而後輕鬆地提交到測試環境,並最終進入生產環境
  2. 可以在讓獨立的服務或應用程序在不一樣的環境中獲得相同的運行結果
  3. 建立隔離的環境來進行測試
  4. 高性能、超大規劃的宿主機部署,高效的資源利用,docker 容器不須要額外的虛擬化管理程序(虛擬機)
  5. 一次建立與配置,以後能夠在任意地方,任意時間讓應用正常的運行

各系統環境安裝docker

mac
docker下載,官網下載太慢,網盤地址 https://pan.baidu.com/s/1i47ETj3 密碼: r76shtml

須要掛載的目錄須要在 Docker -> Preferences... -> File Sharing 添加。
windows 7 安裝 https://segmentfault.com/n/13...python

linuxmysql

sudo yum update

sudo yum install docker
#安裝程序將docker程序安裝到/usr/bin⺫⽬目錄下,配置⽂文件安裝在/etc/sysconfig/docker。安裝好docker以後,能夠 將docker加⼊入到啓動服務組中 
sudo systemctl enable docker.service

#手動啓動docker服務器,使⽤用命令 sudo systemctl start docker.service

目錄結構 github地址 https://github.com/yeyute/doc...linux

docker_lnmpr
├── mysql
│   └── Dockerfile
    └── mysqld.cnf
├── nginx
│   ├── Dockerfile
│   ├── nginx.conf
│   └── vhost
│       └── www.texixi.com.conf
├── php
│   ├── Dockerfile
│   ├── composer.phar
│   ├── php-fpm.conf
│   ├── php.ini
│   ├── redis-3.0.0.tgz
└── redis
    └── Dockerfile
    └── redis.conf

創建鏡像與容器

# build
docker build -t centos/nginx:v1.11.5  ./nginx
docker build -t centos/mysql:v5.7  ./mysql
docker build -t centos/php:v7.0.12 ./php
docker build -t centos/redis:v3.2.6 ./redis

#備註:這裏選取了172.172.0.0網段,也能夠指定其餘任意空閒的網段
docker network create --subnet=172.171.0.0/16 docker-at

# run
docker run --name mysql57 --net docker-at --ip 172.171.0.9 -d -p 3306:3306 -v /data/mysql:/var/lib/mysql -v /data/logs/mysql:/var/log/mysql -v /data/run/mysqlmysqld:/var/run/mysqld  -e MYSQL_ROOT_PASSWORD=123456 -it centos/mysql:v5.7
docker run --name redis326 --net docker-at --ip 172.171.0.10 -d -p 6379:6379  -v /data:/data -it centos/redis:v3.2.6
docker run --name php7 --net docker-at --ip 172.171.0.8 -d -p 9000:9000 -v /www:/www -v /data:/data --link mysql57:mysql57 --link redis326:redis326 -it centos/php:v7.0.12 
docker run --name nginx11 --net docker-at --ip 172.171.0.7 -p 80:80 -d -v /www:/www -v /data:/data --link php7:php7 -it centos/nginx:v1.11.5

經常使用命令

  • docker start 容器名(容器ID也能夠)
  • docker stop 容器名(容器ID也能夠)
  • docker run 命令加 -d 參數,docker 會將容器放到後臺運行
  • docker ps 正在運行的容器
  • docker logs --tail 10 -tf 容器名 查看容器的日誌文件,加-t是加上時間戳,f是跟蹤某個容器的最新日誌而沒必要讀整個日誌文件
  • docker top 容器名 查看容器內部運行的進程
  • docker exec -d 容器名 touch /etc/new_config_file 經過後臺命令建立一個空文件
  • docker run --restart=always --name 容器名 -d ubuntu /bin/sh -c "while true;do echo hello world; sleep 1; done" 不管退出代碼是什麼,docker都會自動重啓容器,能夠設置 --restart=on-failure:5 自動重啓的次數
  • docker inspect 容器名 對容器進行詳細的檢查,能夠加 --format='{(.State.Running)}' 來獲取指定的信息
  • docker rm 容器ID 刪除容器,注,運行中的容器沒法刪除
  • docker rm docker ps -a -q 這樣能夠刪除全部的容器
  • docker images 列出鏡像
  • docker pull 鏡像名:標籤 拉鏡像
  • docker search 查找docker Hub 上公共的可用鏡像
  • docker build -t='AT/web_server:v1' 命令後面能夠直接加上github倉庫的要目錄下存在的Dockerfile文件。 命令是編寫Dockerfile 以後使用的。-t選項爲新鏡像設置了倉庫和名稱:標籤
  • docker login 登錄到Docker Hub,我的認證信息將會保存到$HOME/.dockercfg,
  • docker commit -m="comment " --author="AT" 容器ID 鏡像的用戶名/倉庫名:標籤 不推薦這種方法,推薦dockerfile
  • docker history 鏡像ID 深刻探求鏡像是如何構建出來的
  • docker port 鏡像ID 端口 查看映射狀況的容器的ID和容器的端口號,假設查詢80端口對應的映射的端口
  • run 運行一個容器, -p 8080:80 將容器內的80端口映射到docker宿主機的某一特定端口,將容器的80端口綁定到宿主機的8080端口,另 127.0.0.1:80:80 是將容器的80端口綁定到宿主機這個IP的80端口上,-P 是將容器內的80端口對本地的宿主機公開
  • http://docs.docker.com/refere... 查看更多的命令
  • docker push 鏡像名 將鏡像推送到 Docker Hub
  • docker rmi 鏡像名 刪除鏡像
  • docker attach 容器ID 進入容器

刪除全部容器和鏡像的命令nginx

docker rm `docker ps -a |awk '{print $1}' | grep [0-9a-z]` 刪除中止的容器
docker rmi $(docker images | awk '/^<none>/ { print $3 }')

進入容器的命令git

[root@iZ287mq5dooZ nginx]# docker inspect --format "{{ .State.Pid }}" 54a454b827e5(容器ID)
20426
[root@iZ287mq5dooZ nginx]# nsenter --target 20426 --mount --uts --ipc --net --pid
[root@bcb14764a7a3 /]#

搭建私有倉庫

# 使用官方提供的registry 鏡像來簡單的搭建本地倉庫
docker run -d -p 5000:5000 -v /data/registry:/tmp/registry registry

# 標記鏡像
docker tag centos/mysql:v5.6 192.168.199.128:5000/mysql56

# 上傳鏡像
docker push 192.168.199.128:5000/mysql56

# 下載鏡像
docker pull 192.168.199.128:5000/mysql56

dockerfile 語法

  • MAINTAINER 標識鏡像的做者和聯繫方式
  • EXPOSE 能夠指定多個EXPOSE向外部公開多個端口,能夠幫助多個容器連接
  • FROM 指令指定一個已經存在的鏡像
  • #號表明註釋
  • RUN 運行命令,會在shell 裏使用命令包裝器 /bin/sh -c 來執行。若是是在一個不支持shell 的平臺上運行或者不但願在shell 中運行,也能夠 使用exec 格式 的RUN指令
  • ENV REFRESHED_AT 環境變量 這個環境亦是用來代表鏡像模板最後的更新時間
  • VOLUME 容器添加捲。一個卷是能夠 存在於一個或多個容器內的特定的目錄,對卷的修改是馬上生效的,對卷的修改不會對更新鏡像產品影響,例:VOLUME["/opt/project","/data"]
  • ADD 將構建環境 下的文件 和目錄複製到鏡像 中。例 ADD nginx.conf /conf/nginx.conf 也能夠是取url 的地址文件,若是是壓縮包,ADD命令會自動解壓、
  • USER 指定鏡像用那個USER 去運行
  • COPY 是複製本地文件,而不會去作文件提取(解壓包不會自動解壓) 例:COPY conf.d/ /etc/apache2/ 將本地conf.d目錄中的文件複製到/etc/apache2/目錄中

問題點整理

  • docker 服務沒啓動

啓動並設置爲開機自動啓動docker服務github

[root@iZ287mq5dooZ docker-php]# docker info
Cannot connect to the Docker daemon. Is the docker daemon running on this host?
[root@iZ287mq5dooZ docker-php]# ps aux | grep docker
root      7902  0.0  0.0 112648   956 pts/0    S+   13:54   0:00 grep --color=auto docker
[root@iZ287mq5dooZ docker-php]# service docker start
Redirecting to /bin/systemctl start  docker.service
[root@iZ287mq5dooZ redis]# systemctl start docker
  • 注意掛載目錄的權限問題,否則容器成功啓動幾秒後馬上關閉

例:如下/data/run/mysql 目錄沒權限的狀況下就會出現剛纔那種狀況web

docker run --name mysql57 -d -p 3306:3306 -v /data/mysql:/var/lib/mysql -v /data/logs/mysql:/var/log/mysql -v /data/run/mysql:/var/run/mysqld -e MYSQL_ROOT_PASSWORD=123456 -it centos/mysql:v5.7
  • 須要注意php.ini 中的目錄對應 mysql 的配置的目錄須要掛載才能獲取文件內容,否則php鏈接mysql失敗redis

    # php.ini
    mysql.default_socket = /data/run/mysql/mysqld.sock
    mysqli.default_socket = /data/run/mysql/mysqld.sock
    pdo_mysql.default_socket = /data/run/mysql/mysqld.sock
    
    # mysqld.cnf
    pid-file       = /var/run/mysqld/mysqld.pid
    socket         = /var/run/mysqld/mysqld.sock
  • 宿主機 沒法訪問docker的容器(nginx) https://segmentfault.com/q/10...,我的提問與回答都在裏面
  • 使用php鏈接不上redis

    # 錯誤的
    $redis = new Redis;
    $rs = $redis->connect('127.0.0.1', 6379);

    php鏈接不上,查看錯誤日誌

    PHP Fatal error:  Uncaught RedisException: Redis server went away in /www/index.php:7

    考慮到docker 之間的通訊應該不能夠用127.0.0.1 應該使用容器裏面的ip,因此查看redis 容器的ip

    [root@iZ287mq5dooZ php]# docker ps 
    CONTAINER ID        IMAGE                  COMMAND                   CREATED             STATUS              PORTS                         NAMES
    5fb4b1904f1c        centos/nginx:v1.11.5   "/usr/local/nginx/sbi"    About an hour ago   Up About an hour    0.0.0.0:80->80/tcp, 443/tcp   nginx11
    2bf7ad9f44f9        centos/php:v7.0.12     "/usr/local/php/sbin/"    About an hour ago   Up About an hour    0.0.0.0:9000->9000/tcp        php7
    4b84858ea4e4        centos/redis:v3.2.6    "/bin/sh -c '\"/usr/lo"   18 hours ago        Up About an hour    0.0.0.0:6379->6379/tcp        redis326
    158c67aa178c        centos/mysql:v5.7      "docker-entrypoint.sh"    6 days ago          Up About an hour    0.0.0.0:3306->3306/tcp        mysql57
    [root@iZ287mq5dooZ php]# docker inspect 4b84858ea4e4

    結果是爲 192.168.0.4,測試鏈接,成功

    $redis = new Redis;
    $rs = $redis->connect('192.168.0.4', 6379);

    問題是重啓容器ip爲動態的,解決該問題
    第一步:建立自定義網絡

    #備註:這裏選取了172.172.0.0網段,也能夠指定其餘任意空閒的網段
    docker network create --subnet=172.171.0.0/16 docker-at
    docker run --name redis326 --net docker-at --ip 172.171.0.10 -d -p 6379:6379  -v /data:/data -it centos/redis:v3.2.6

    鏈接redis 就能夠配置對應的ip地址了,鏈接成功

    $redis = new Redis;
    $rs = $redis->connect('172.171.0.10', 6379);

以上狀況雖然容器之間關聯了,可是容器之間的通信須要用搭建的網段的鏈接。
假設:只有mysql 的容器,咱們機器掛載了3306的端口,咱們本地能夠127.0.0.1去鏈接mysql容器服務
可是假設php服務也在容器裏面,這時就不能夠這麼鏈接,由於是php容器去鏈接mysql容器,因此須要一個鏈接的ip。

  • 使用docker-compose 報錯

    // 使用pip 安裝docker-compose
     pip install -U docker-compose

    假設沒安裝pip,會報如下錯誤,windows 請參數 http://www.cnblogs.com/RSsky/...

    bash: pip: command not found

    linux 請執行

    yum install python-pip

安全檢測工具

Docker bench,clair 等

鏡像體積優化(目前我的使用的centos,沒有作優化)

  1. centos的基礎鏡像接近200m 能夠考慮使用Alpine 的基礎鏡像,才4.999M
  2. Docker 鏡像的儲存原理是分層的,docker build 的過程就是 docker 運行了一個容器,而後執行 Dockerfile 裏寫的命令。而且每個命令都會 commit 一下,每一次 commit 都是一層一層的疊加在原來的鏡像上,也就是說在某一層裏增長了一個文件,在下一層裏刪除這個文件,是沒有任何效果的,鏡像體積是不變的,可能反而會增長
相關文章
相關標籤/搜索