浅谈Docker

440 阅读10分钟

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.4nginx/www/wwwroot/2007_SRM/00-1/lrnp/nginx/conf:/conf81:80
php7php7/www/wwwroot/2007_SRM/00-1/lrnp/www:/www 9001:90009001:9000
redis5redis5/www/wwwroot/2007_SRM/00-1/lrnp/redis:/redis6379: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.4nginx/.../lrnp/nginx/conf:/conf81:80172.100.100.10
php7php7/.../lrnp/www:/www9001:9000172.100.100.20
redis5redis5/.../lrnp/redis:/redis6379:6379172.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

相关文章

www.cnblogs.com/minseo/p/11…

7.1 安装

官网地址:docs.docker.com/compose/

[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 foramteDocker Engine
11.9.0+
2.01.10.0+
2.11.12.0+
2.2,3.0,3.1,3.21.13.0+
2.3,3.3,3.4,3.517.06.0+
2.417.12.0+
3.618.02.0+
3.718.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]#