Docker 是一个开源的运用容器引擎,让开发者可以打包他们的运用以及依赖包到一个可移植的容器中,然后发布到任何盛行的 Linux 机器上,也可以实现虚拟化。容器是完备利用沙箱机制,相互之间不会有任何接口。推举内核版本3.8及以上
为什么利用Docker
linux

# 下载安装curl -sSL https://get.docker.com/ | sh# 设置开机自启sudo systemctl enable docker.servicesudo service docker start|restart|stop# 安装docker-composecurl -L https://github.com/docker/compose/releases/download/1.23.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-composechmod +x /usr/local/bin/docker-compose
目录构造
docker_lnmp├── v2├── mysql│ └── Dockerfile│└── my.cnf├── nginx│ ├── Dockerfile│ ├── nginx.conf│ ├── log│ │ └── error.log│ └── www│ ├── index.html│ ├── index.php│ ├── db.php│ └── redis.php├── php│ ├── Dockerfile│ ├── www.conf│ ├── php-fpm.conf│ ├── php.ini│ └── log│ └── php-fpm.log└── redis └── Dockerfile └── redis.conf
创建镜像与安装
直策应用docker-compose一键制作镜像并启动容器
版本一
该版本是通过拉取纯净的CentOS镜像,通过Dockerfile干系命令进行源码编译安装各个做事。以是该办法很方便定制自己须要的镜像,但是占用空间大且构建慢。
git clone https://github.com/voocel/docker-lnmp.gitcd docker-lnmpdocker-compose up -d
版本二(推举)
git clone https://github.com/voocel/docker-lnmp.gitcd docker-lnmp/v2chmod 777 ./redis/redis.logchmod -R 777 ./redis/datadocker-compose up -d
该版本是通过拉取官方已经制作好的各个做事的镜像,再通过Dockerfile干系命令根据自身需求做相应的调度。以是该办法构建迅速利用方便,由于是基于Alpine Linux以是占用空间很小。
测试
利用docker ps查看容器启动状态,若全部正常启动了则 通过访问127.0.0.1、127.0.0.1/index.php、127.0.0.1/db.php、127.0.0.1/redis.php 即可完成测试 (若想利用https则请修正nginx下的dockerfile,和nginx.conf按提示去掉注释即可,灵须要在ssl文件夹中加入自己的证书文件,本项目自带的是空的,须要自己更换,保持文件名同等)
进入容器内部
利用 docker execdocker exec -it ngixn /bin/sh利用nsenter命令
# cd /tmp; curl https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz | tar -zxf-; cd util-linux-2.24;# ./configure --without-ncurses# make nsenter && sudo cp nsenter /usr/local/bin
为了连接到容器,你还须要找到容器的第一个进程的 PID,可以通过下面的命令获取再实行。
PID=$(docker inspect --format \"大众{{ .State.Pid }}\"大众 container_id)# nsenter --target $PID --mount --uts --ipc --net --pid
PHP扩展安装
安装PHP官方源码包里的扩展(如:同时安装pdo_mysql mysqli pcntl gd四个个扩展)在php的Dockerfile中加入以下命令
RUN apk add libpng-dev \ && docker-php-ext-install pdo_mysql mysqli pcntl gd \
注:由于该镜像短缺gd库所需的libpng-dev包,以是须要先下载这个包
PECL 扩展安装# 安装扩展RUN pecl install memcached-2.2.0 \ # 启用扩展 && docker-php-ext-enable memcached \通过下载扩展源码,编译安装的办法安装
# 安装Redis和swoole扩展RUN cd ~ \ && wget https://github.com/phpredis/phpredis/archive/4.2.0.tar.gz \ && tar -zxvf 4.2.0.tar.gz \ && mkdir -p /usr/src/php/ext \ && mv phpredis-4.2.0 /usr/src/php/ext/redis \ && docker-php-ext-install redis \ && apk add libstdc++\ && cd ~ \ && wget https://github.com/swoole/swoole-src/archive/v4.2.12.tar.gz \ && tar -zxvf v4.2.12.tar.gz \ && mkdir -p /usr/src/php/ext \ && mv swoole-src-4.2.12 /usr/src/php/ext/swoole \ && docker-php-ext-install swoole \
注:由于该镜像须要先安装swoole依赖的libstdc++,否则安装成功后无法正常加载swoole扩展
Composer安装
在Dockerfile中加入
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer \
常见问题处理
redis启动失落败问题 在v2版本中redis的启动用户为redis不是root,以是在宿主机中挂载的./redis/redis.log和./redis/data须要有写入权限。chmod 777 ./redis/redis.log chmod 777 ./redis/dataMYSQL连接失落败问题 在v2版本中是最新的MySQL8,而该版本的密码认证办法为Caching_sha2_password,而低版本的php和mysql可视化工具可能不支持,可通过phpinfo里的mysqlnd的Loaded plugins查看是否支持该认证办法,否则须要修正为原来的认证办法mysql_native_password:
select user,host,plugin,authentication_string from mysql.user; ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456'; FLUSH PRIVILEGES;把稳挂载目录的权限问题,不然容器成功启动几秒后急速关闭,例:以下/data/run/mysql 目录没权限的情形下就会涌现刚才那种情形 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失落败
``` # 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 ```利用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@localhost docker]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESb5f7dcecff4c docker_nginx \"大众/usr/sbin/nginx -...\公众 4 seconds ago Up 3 seconds 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp nginx60fd2df36d0e docker_php \"大众/usr/local/php/sb...\公众 7 seconds ago Up 5 seconds 9000/tcp php7c7df6f8eb91 hub.c.163.com/library/mysql:latest \"大众docker-entrypoint...\"大众 12 seconds ago Up 11 seconds 3306/tcp mysqla0ebd39f0f64 docker_redis \公众usr/local/redis/s...\"大众 13 seconds ago Up 12 seconds 6379/tcp redis把稳测试的时候连接地址须要容器的ip或者容器名names,比如redis、mysql. 例如nginx配置php文件解析 fastcgi_pass php:9000; 例如php连接redis res = $redis->connect('redis', 6379);由于容器ip是动态的,重启之后就会变革,以是可以创建静态ip第一步:创建自定义网络
#备注:这里选取了172.172.0.0网段,也可以指定其他任意空闲的网段docker network create --subnet=172.171.0.0/16 docker-atdocker run --name redis326 --net docker-at --ip 172.171.0.20 -d -p 6379:6379 -v /data:/data -it centos/redis:v3.2.6连接redis 就可以配置对应的ip地址了,连接成功
$redis = new Redis;$rs = $redis->connect('172.171.0.20', 6379);其余还有种可能phpredis连接不上redis,须要把redis.conf配置略作修正。
bind 127.0.0.1改为:bind 0.0.0.0启动docker web做事时 虚拟机端口转发 外部无法访问 一样平常涌如今yum update的时候(WARNING: IPv4 forwarding is disabled. Networking will not work.)或者宿主机可以访问,但外部无法访问
vi /etc/sysctl.conf或者vi /usr/lib/sysctl.d/00-system.conf添加如下代码: net.ipv4.ip_forward=1重启network做事systemctl restart network查看是否修正成功sysctl net.ipv4.ip_forward如果返回为\"大众net.ipv4.ip_forward = 1\公众则表示成功了如果利用最新的MySQL8无法正常连接,由于最新版本的密码加密办法改变,导致无法远程连接。
# 修正密码加密办法ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
常用命令
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 -aq) 删除所有容器docker rmi $(docker images -aq) 删除所有镜像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 镜像的用户名/仓库名:标签 不推举这种方法,推举dockerfiledocker 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端口对本地的宿主机公开docs.docker.com/reference/b… 查看更多的命令docker push 镜像名 将镜像推送到 Docker Hubdocker rmi 镜像名 删除镜像docker attach 容器ID 进入容器############################################################docker network create --subnet=172.171.0.0/16 docker-at 选取172.172.0.0网段docker build 就可以加 -ip指定容器ip 172.171.0.10 了删除所有容器和镜像的命令
docker rm `docker ps -a |awk '{print $1}' | grep [0-9a-z]` 删除停滞的容器docker rmi $(docker images | awk '/^<none>/ { print $3 }')
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-compose.yml 语法解释
image 指定为镜像名称或镜像ID。如果镜像不存在,Compose将考试测验从互联网拉取这个镜像build 指定Dockerfile所在文件夹的路径。Compose将会利用他自动构建这个镜像,然后利用这个镜像command 覆盖容器启动后默认实行的命令links 链接到其他做事容器,利用做事名称(同时作为别名)或做事别名(SERVICE:ALIAS)都可以external_links 链接到docker-compose.yml外部的容器,乃至并非是Compose管理的容器。参数格式和links类似ports 暴露端口信息。宿主机器端口:容器端口(HOST:CONTAINER)格式或者仅仅指定容器的端口(宿主机器将会随机分配端口)都可以(把稳:当利用 HOST:CONTAINER 格式来映射端口时,如果你利用的容器端口小于 60 你可能会得到缺点得结果,由于 YAML 将会解析 xx:yy 这种数字格式为 60 进制。以是建议采取字符串格式。)expose 暴露端口,与posts不同的是expose只可以暴露端口而不能映射到主机,只供外部做事连接利用;仅可以指定内部端口为参数volumes 设置卷挂载的路径。可以设置宿主机路径:容器路径(host:container)或加上访问模式(host:container:ro)ro便是readonly的意思,只读模式volunes_from 挂载另一个做事或容器的所有数据卷environment 设置环境变量。可以属于数组或字典两种格式。如果只给定变量的名称则会自动加载它在Compose主机上的值,可以用来防止透露不必要的数据env_file 从文件中获取环境变量,可以为单独的文件路径或列表。如果通过docker-compose -f FILE指定了模板文件,则env_file中路径会基于模板文件路径。如果有变量名称与environment指令冲突,则往后者为准(环境变量文件中每一行都必须有注释,支持#开头的注释行)extends 基于已有的做事进行做事扩展。例如我们已经有了一个webapp做事,模板文件为common.yml。编写一个新的 development.yml 文件,利用 common.yml 中的 webapp 做事进行扩展。后者会自动继续common.yml中的webapp做事及干系的环境变量net 设置网络模式。利用和docker client 的 --net 参数一样的值pid 和宿主机系统共享进程命名空间,打开该选项的容器可以相互通过进程id来访问和操作dns 配置DNS做事器。可以是一个值,也可以是一个列表cap_add,cap_drop 添加或放弃容器的Linux能力(Capability)dns_search 配置DNS搜索域。可以是一个值也可以是一个列表把稳:利用compose对Docker容器进行编排管理时,须要编写docker-compose.yml文件,初次编写时,随意马虎碰着一些比较低级的问题,导致实行docker-compose up时先解析yml文件的缺点。比较常见的是yml对缩进的严格哀求。yml文件还行后的缩进,不许可利用tab键字符,只能利用空格,而空格的数量也有哀求,一样平常两个空格。关注我:私信回答“555”获取往期Java高等架构资料、源码、条记、视频Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架构技能往期架构视频截图