1.理解docker
1.1 docker是什么?
看看官方概念:
Docker 是一个开源的应用容器引擎,你可以将其理解为一个轻量级的虚拟机,开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上。
这里我们来点通俗的:
比如:一台机器上,运行了3个docker, 每个docker里面分别运行着nginx,php和mysql。你想把这台机器上的nginx,php和mysql部署到另外10台机器。直接执行一系列docker命令就可以了,是不是很 简单?
1.2 为什么要使用Docker
作为一种新兴的虚拟化方式,Docker跟传统的虚拟化方式相比具有众多的优势。
1.2.1 更高效的利用系统资源
由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相 同配置的主机,往往可以运行更多数量的应用。
1.2.2 更快速的启动时间
传统的虚拟机技术启动应用服务往往需要数分钟,而Docker容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。
1.2.4 一致的运行环境
开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些bug并未在开发过程中被发现。而Docker的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性, 从而不会再出现**「这这段段代代码码在在我我机机器器上上没没问问题题啊啊」**这类问题。
1.2.5 持续交付和部署
对开发和运维(DevOps)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运 行。 使用Docker可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile来进行镜像构建,并结合持续集成(Continuous Integration) 系统进行集成测试, 而运维人员则可以直接在生产环境中 快速部署该镜像,甚至结合持续部署(Continuous Delivery/Deployment) 系统进行自动部署。 而且使用Dockerfile使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。
1.2.6 更轻松的迁移
台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。
1.2.7 更轻松的维护和扩展
Docker使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker团队同各个开源项目团队一起维护了一大批 高质量的官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。
对比传统虚拟机总结
| 特性 | 容器 | 虚拟机 |
|---|---|---|
| 启动 | 秒级 | 分钟级 |
| 硬盘使用 | 一般为MB | 一般为GB |
| 性能 | 接近原生 | 弱于 |
| 系统支持量 | 单机支持上千个容器 | 一般几十个 |
2.docker安装
-- 1. 卸载老版本
$ yum -y remove docker docker-common docker-selinux docker-engine
-- 2. 安装需要的软件包
$ yum install -y yum-utils device-mapper-persistent-data lvm2
-- 3. 设置国内yum源
$ yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
-- 4. 查看docker版本
$ yum list docker-ce --showduplicates|sort -r
-- 5. 安装
$ yum install docker-ce-18.03.1.ce -y
-- 6. 配置docker镜像源
$ vi /etc/docker/daemon.json
{
"registry-mirrors": ["http://hub-mirror.c.163.com"]
}
-- 7. 启动
$ systemctl start docker
-- 8.加入开机自启
systemctl enable docker
3.docker-容器,镜像,仓库,dockerfile,docker-compose
Docker 容器,镜像,仓库,dockerfile,docker-compose
- 镜像((Image):例如:一个镜像可以包含一个完整的 ubuntu 操作系统环境,里面仅安装了 Apache 或用户需要的其它应用程序。也有比如PHP镜像,nginx镜像。 镜像可以用来创建 Docker 容器。用户可以直接 从其他人那里下载一个已经做好的镜像来直接使用。
一个镜像好比是一个盗版的windows光碟文件,它可以装无数个window系统。同样的,一个PHP docker镜像,也可以装无数个PHP。
- 容器((Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
一个镜像好比是一个盗版的windows光碟文件,它可以装无数个window系统。装好了的系统,你可以理解为一个容器。同样的,一个PHP docker镜像,也可以装无数个PHP,装好了的PHP,就是一个docker容器。
- 仓库((Repository):仓库是集中存放镜像文件的场所。
有时候会把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。实际上,仓库注册服务器上往往存放着多个仓库, 每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。 仓库分为公开仓库(Public)和私有仓库(Private)两种形式。 最大的公开仓库是 Docker Hub,存放了数量庞大的镜像供用户下载。
- dockerfile:仓库是集中存放镜像文件的场所。
Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。 具体的我们查看给大家的pdf的书籍,命令都是简单 的,我们会慢慢的去学习
这种方式是比较流行的方式。就是将需要对镜像的操作全部写到一个文件中,然后使用docker build命令从这个文件中创建镜像 这种方法可以使镜像的创建变得透明化和独立化,并且创建过程可以被 重复执行 dockerfile文件以行位单位,性首为dockerfile命令,命令都是大写形式,期后紧跟着的是命令的参数。
- dockerfile:仓库是集中存放镜像文件的场所。
Compose是 Docker 的服务编排工具,诞生主要是来帮助开发或运维人员很好地管理docker容器 减少繁琐的单个容器创建、删除等操作,比较适合组合使用多个容器进行开发的场景。
对于需要多个容器的操作,传统的方式是一个个的创建及运行,而composer则只需要通过一次性把这些命令写在docker-composer.yml文件中 以后每次启动这一整个环境的时候,只需要你只要敲一 个 docker-composer up命令就ok了
4.快速入门
4.0 常用命令
============= 操作仓库 =============
-- 1. 从仓库上下载镜像资源到本地
docker pull xxx/yyy
-- 2. 推送本地镜像到仓库
docker push xxx/yyy
============= 操作镜像 =============
-- 1. 查看所有的镜像
docker images
-- 2. 删除镜像
docker rmi xxx/yyy
-- 3. 删除所有镜像
docker rmi $(docker images)
-- 4. 根据dockerfile构建镜像
docker build -t [镜像名称] .
-- 5. 强制删除镜像
docker rmi -f xxx/yyy
-- 6. 查看镜像的构建历史
docker history 镜像
============= 操作容器 =============
-- 1. 查看运行的容器
docker ps
-- 2. 查看所有容器(含未运行的)
docker ps -a
-- 3. 创建容器
docker run -itd --name 容器名称(自定义) 镜像名称
-- 4. 进入容器中
docker exec -it 容器名称 挂起命令(top,ping,sh,bash...)
-- 5. 容器转为镜像
docker commit -m="猫叔" 容器 镜像名称
-- 6. 启动容器
docker start 容器名
-- 7. 停止容器
docker stop 容器名
-- 8. 删除容器
docker rm 容器名
-- 9. 删除所有容器
docker rm $(docker ps -a -q)
============= 网络环境配置 =============
-- 1. 查看所有网络配置
docker network ls
-- 2. 创建网络
docker network create --subnet=172.100.100.0/24 mynetwork
-- 3. 删除网络
docker network rm mynetwork
-- 4. 给容器定义网络 --network=网络名 --ip=自定义ip
docker run -itd --network=mynetwork --ip=172.100.100.100 --name 容器名称(自定义) 镜像名称
============= 导出备份 =============
-- 1. 根据 容器 导出tar文件
docker export 容器名 > 文件名.tar
-- 2. 根据 容器 导出的tar文件转为镜像
docker import 文件名.tar 镜像名
-- 3. 根据 镜像 导出tar文件
docker save 镜像名 > 文件名.tar
-- 4. 根据 镜像 导出的tar文件转为镜像
docker load < 文件名.tar
4.1 从仓库-》镜像-》容器
从仓库-》镜像-》容器
[root@localhost ~]# docker pull centos:centos7
centos7: Pulling from library/centos
524b0c1e57f8: Pull complete
Digest: sha256:e9ce0b76f29f942502facd849f3e468232492b259b9d9f076f71b392293f1582
Status: Downloaded newer image for centos:centos7
从仓库下载centos7的镜像文件到本地
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos centos7 b5b4d78bc90c 2 months ago 203MB
构建容器操作
[root@localhost ~]# docker run -itd --name centos centos:centos7
45de099e5ec0a896ae510be298175c4ac28519fa07e57347e0784f1dbea20fcd
[root@localhost ~]# docker exec -it centos bash
[root@45de099e5ec0 /]# ls
anaconda-post.log dev home lib64 mnt proc run srv tmp var
bin etc lib media opt root sbin sys usr
4.2 从dockerfile-》镜像-》容器
创建一份dockerfile文件
FROM centos:centos7
基于dockerfile构建镜像
[root@localhost centos]# docker build -t centos_images .
Sending build context to Docker daemon 2.048kB
Step 1/1 : FROM centos:centos7
---> b5b4d78bc90c
Successfully built b5b4d78bc90c
Successfully tagged centos_images:latest
t [root@localhost centos]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos centos7 b5b4d78bc90c 2 months ago 203MB
centos_images latest b5b4d78bc90c 2 months ago 203MB
- 为什么那么快?因为docker在本地找到了centos7的镜像所以就不会用仓库的了
同样也可以运用dockerfile构建的镜像来创建容器
[root@localhost centos]# docker run -itd --name centos_images centos_images
696743b0aaa4b5463f54f75f709ce35aece58481b8c2de5c5f4f723de43c0a23
[root@localhost centos]# docker exec -it centos_images bash
[root@696743b0aaa4 /]# ls
anaconda-post.log dev home lib64 mnt proc run srv tmp var
bin etc lib media opt root sbin sys usr
5.通过docker构建nginx+php+redis环境
每个Dockerfile中的内容
5.1 Redis
redis
FROM alpine:3.11
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
&& apk add gcc g++ libc-dev wget vim openssl-dev make linux-headers \
&& rm -rf /var/cache/apk/*
COPY ./redis-5.0.7.tar.gz redis-5.0.7.tar.gz
#通过选择更小的镜像,删除不必要文件清理不必要的安装缓存,从而瘦身镜像 #创建相关目录能够看到日志信息跟数据跟配置文件 sh
RUN mkdir -p /usr/src/redis \
&& mkdir -p /redis/data \
&& mkdir -p /redis/conf \
&& mkdir -p /redis/log \
&& mkdir -p /var/log/redis \
&& tar -zxvf redis-5.0.7.tar.gz -C /usr/src/redis \
&& rm -rf redis-5.0.7.tar.gz \
&& cd /usr/src/redis/redis-5.0.7 && make \
&& cd /usr/src/redis/redis-5.0.7
&& make install;
EXPOSE 6379
# CMD ["redis-server","/redis/conf/redis.conf"]
# ENTRYPOINT ["redis-server", "/usr/src/redis/redis-5.0.7/redis.conf"]
5.2 Nginx
nginx
FROM centos:centos7
RUN groupadd -r nginx && useradd -r -g nginx nginx
#添加centos源(先下载wget)
COPY ./epel-7.repo /etc/yum.repos.d/epel.repo
RUN mkdir /data \
&& mkdir /conf \
&& yum update -y \
&& yum clean all \
&& yum makecache \
&& yum -y install gcc gcc-c++ autoconf automake make zlib zlib-devel net-tools openssl* pcre* wget \
&& yum clean all && rm -rf /var/cache/yum/*
#声明匿名卷
VOLUME /data
COPY ./nginx-1.14.1.tar.gz /data/nginx-1.14.1.tar.gz
RUN cd /data \
&& tar -zxvf nginx-1.14.1.tar.gz \
&& cd nginx-1.14.1 \
&& ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx \
&& make && make install && rm -rf /data/nginx-1.14.1.tar.gz && rm -rf /data/nginx-1.14. \
&& ln -s /usr/local/nginx/sbin/* /usr/local/sbin
COPY ./conf/nginx.conf /conf
#进入容器时默认打开的目录
WORKDIR /conf
#声明端口
EXPOSE 80
#容器启动的时候执行,在docker run过程当中是会被其他指令替代
#CMD ["/usr/local/nginx/sbin/nginx","-c","/conf/nginx.conf","-g","daemon off;"]
#执行一条指
ENTRYPOINT ["/usr/local/nginx/sbin/nginx","-c","/conf/nginx.conf","-g","daemon off;"]
5.3 PHP
php
FROM php:7.3-fpm-alpine
# Version
ENV PHPREDIS_VERSION 4.0.0
# Libs
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
&& apk add \
curl \
vim \
wget \
git \
openssl-dev\
zip \
unzip \
g++ make autoconf
# docker方式安装PDO extension # 安装扩展
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" \
&& docker-php-ext-install pdo_mysql \
&& docker-php-ext-install pcntl \
&& docker-php-ext-install sysvmsg
# Redis extension
RUN wget http://pecl.php.net/get/redis-${PHPREDIS_VERSION}.tgz -O /tmp/redis.tar.tgz \
&& pecl install /tmp/redis.tar.tgz \
&& rm -rf /tmp/redis.tar.tgz \
&& docker-php-ext-enable redis
# 修改php.ini的文件 extension=redis.so
EXPOSE 9000
#设置工作目录
WORKDIR /www
5.4 构建
然后构建镜像
docker build -t php7 .
docker build -t nginx .
docker build -t redis5 .
再构建容器
| 容器名称 | 镜像名称 | 共享目录 | 端口 |
|---|---|---|---|
| nginx1.4 | nginx | /www/wwwroot/2007_SRM/00-1/lrnp/nginx/conf:/conf | 81:80 |
| php7 | php7 | /www/wwwroot/2007_SRM/00-1/lrnp/www:/www 9001:9000 | 9001:9000 |
| redis5 | redis5 | /www/wwwroot/2007_SRM/00-1/lrnp/redis:/redis | 6379:6379 |
- 注意:需要注意配置nginx的的配置和redis配置
docker run -itd -p 81:80 -v /www/wwwroot/2007_SRM/00-1/lrnp/nginx/conf:/conf --name nginx1.4 nginx
docker run -itd -p 9001:9000 -v /www/wwwroot/2007_SRM/00-1/lrnp/www:/www --name php7 php7
docker run -itd -p 6379:6379 -v /www/wwwroot/2007_SRM/00-1/lrnp/redis:/redis --name redis5 redis5
-v:这个参数的作用就是让容器与宿主机的目录同步
格式:-v 宿主机目录地址:容器目录地址
-p:这个是让容器和宿主机绑定在一起
格式:-p 宿主机端口:容器端口
注意: 一定要执行 docker top检测是否运行相应进程
[root@localhost lrnp]# docker top php7
UID PID PPID C STIME TTY TIME CMD
root 34583 34566 0 04:44 ? 00:00:00 php-fpm: master process (/usr/local/etc/php- fpm.conf)
82 34628 34583 0 04:44 ? 00:00:00 php-fpm: pool www
82 34629 34583 0 04:44 ? 00:00:00 php-fpm: pool www
[root@localhost lrnp]# docker top redis5
UID PID PPID C STIME TTY TIME CMD
root 34674 34657 0 04:44 ? 00:00:00 redis-server *:6379
[root@localhost lrnp]# docker top nginx1.4
UID PID PPID C STIME TTY TIME CMD
root 34495 34478 0 04:44 ? 00:00:00 nginx: master process
/usr/local/nginx/sbin/nginx -c /conf/nginx.conf -g daemon off;
root 34528 34495 0 04:44 ? 00:00:00 nginx: worker process
[root@localhost lrnp]#
为什么访问不成功
- 可能三个容器都没有启动成功
- 容器中的程序没有启动成功
- 目录地址不对
- 端口的配置开放问题
- 防火墙问题
6.网络配置
目前的情况是根据宿主机ip以及暴露的port进行lnrp环境间的通信;
[root@localhost lrnp]# docker network create --subnet=172.100.100.0/24 lrnp
857964f4f251f04a755a6da1e82160038fab024b042c2d40f606d58541abf06b
[root@localhost lrnp]# docker network ls
NETWORK ID NAME DRIVER SCOPE
7ce602860620 bridge bridge local
7891e699e1a9 host host local
857964f4f251 lrnp bridge local
3fb7b0de9e8a none null local
477c3f040371 redis_network bridge local
| 容器名称 | 镜像名称 | 共享目录 | 端口 | ip |
|---|---|---|---|---|
| nginx1.4 | nginx | /.../lrnp/nginx/conf:/conf | 81:80 | 172.100.100.10 |
| php7 | php7 | /.../lrnp/www:/www | 9001:9000 | 172.100.100.20 |
| redis5 | redis5 | /.../lrnp/redis:/redis | 6379:6379 | 172.100.100.30 |
先删除所有容器
docker stop $(docker ps -a -q) | xargs docker rm
重新构建容器
- 注意:需要注意配置nginx的配置和redis配置 目前采用的是ip和port的方式连接了
docker run -itd --network=lrnp --ip=172.100.100.10 -p 81:80 -v /www/wwwroot/2007_SRM/00-1/lrnp/nginx/conf:/conf --name nginx1.4 nginx
docker run -itd --network=lrnp --ip=172.100.100.20 -p 9001:9000 -v /www/wwwroot/2007_SRM/00-1/lrnp/www:/www --name php7 php7
docker run -itd --network=lrnp --ip=172.100.100.30 -p 6379:6379 -v /www/wwwroot/2007_SRM/00-1/lrnp/redis:/redis --name redis5 redis5
7.docker-compose
这个工具是做什么呢?可以帮助我们快速的构建和对容器的启动以及停止等操作
介绍
- Compose是 Docker 的服务编排工具,诞生主要是来帮助开发或运维人员很好地管理docker容器;减少繁琐的单个容器创建、删除等操作,比较适合组合使用多个容器进行开发的场景。
- 对于需要多个容器的操作,传统的方式是一个个的创建及运行,而composer则只需要通过一次性把这些命令写在docker-composer.yml文件中,以后每次启动这一整个环境的时候,只需要你只要敲一个 docker- composer up命令就ok了。
7.0 相关命令
-- 1. 启动
docker-compose up -d # 启动命令
docker-compose stop
docker-compose down
相关文章
7.1 安装
[root@localhost lrnp]# curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 423 100 423 0 0 476 0 --:--:-- --:--:-- --:--:-- 476
100 16.7M 100 16.7M 0 0 1867k 0 0:00:09 0:00:09 --:--:-- 1975k
修改权限
chmod +x /usr/local/bin/docker-compose
安装完成后可以查看版本
docker-compose --version
7.2 运用
docker-compose的默认模版文件为: docker-compose.yml。 和Dockerfile一样,它也是有自己的语法命令的。其中定义的每个服务都必须通过image指令指定镜像或build指令(需要Dockerfile)来自动构建。其它大部分指令 都跟docker run中的类似。
需要注意的是docker-composer运用的时候一定要注意版本的问题,如下图显示
| Compose file foramte | Docker Engine |
|---|---|
| 1 | 1.9.0+ |
| 2.0 | 1.10.0+ |
| 2.1 | 1.12.0+ |
| 2.2,3.0,3.1,3.2 | 1.13.0+ |
| 2.3,3.3,3.4,3.5 | 17.06.0+ |
| 2.4 | 17.12.0+ |
| 3.6 | 18.02.0+ |
| 3.7 | 18.06.0+ |
- 每个docker-compose.yml必须定义image或者build中的一个,其它的是可选的。
- image 指定镜像tag或者ID
# 编排php,redis,nginx容器
version: "3.6" # 确定docker-composer文件的版本
services: # 代表就是一组服务 - 简单来说一组容器
nginx: # 这个表示服务的名称,课自定义; 注意不是容器名称
build: # 根据dockerfile构建镜像及构建为容器
context: ./nginx
image: nginx1.15 # 指定容器的镜像文件
container_name: nginx_compose # 这是容器的名称
ports: # 配置容器与宿主机的端口
- "82:80"
networks: ## 引入外部预先定义的网段
nginx_net:
ipv4_address: 172.15.22.110 #设置ip地址
volumes: # 配置数据挂载
- /www/wwwroot/2007_SRM/00-2/compose/nginx/conf:/conf
working_dir: /conf #工作目录
php: # 这个表示服务的名称,课自定义; 注意不是容器名称
build: # 根据dockerfile构建镜像及构建为容器
context: ./php
image: php7 # 指定容器的镜像文件
container_name: php_compose # 这是容器的名称
ports: # 配置容器与宿主机的端口
- "9002:9000"
networks: ## 引入外部预先定义的网段
nginx_net:
ipv4_address: 172.15.22.120 #设置ip地址
volumes: # 配置数据挂载
- /www/wwwroot/2007_SRM/00-2/compose/php/www:/www
redis: # 这个表示服务的名称,课自定义; 注意不是容器名称
image: redis5 # 指定容器的镜像文件
networks: ## 引入外部预先定义的网段
nginx_net:
ipv4_address: 172.15.22.130 #设置ip地址
container_name: redis_compose # 这是容器的名称
ports: # 配置容器与宿主机的端口
- "6380:6379"
volumes: # 配置数据挂载
- /www/wwwroot/2007_SRM/00-2/compose/redis:/redis
# 设置网络模块
networks:
# 使用之前定义的网络
# lrnp:
# external:
# name: lrnp
# 自定义网络
nginx_net:
driver: bridge
ipam: #定义网段
config:
- subnet: "172.15.22.0/24"
- 注意:需要注意配置nginx的配置和redis配置
[root@localhost composer]# docker-compose up -d
Creating php_compose ... done
Creating nginx_compose ... done
Creating redis_compose ... done
[root@localhost composer]#