docker 概述
docker是什么
- 使用最广泛的肉开源容器引擎 其他如rocket,containerd,pouch等容器引擎
- 一种系统级虚拟化技术 传统的kvm xen,exsi,vmware
- 依赖于Linux内核特性namespace(资源隔离)cgroup(资源限制)
docker设计目标
- 提供简单的应用程序打包
- 开发和运维人员职责逻辑隔离
- 多环境保持一致
docker基本组成
- docker client 客户端
- docker daemon 守护进程
- docker images 镜像
- docker container 容器
- docker registry 镜像仓库
容器VS docker
Container
|
VM
|
|
启动速度
|
秒级
|
分钟级
|
运行性能
|
接近原生
|
5%左右损失
|
磁盘占用
|
MB
|
GB
|
数量
|
成百上千
|
一般几十台
|
隔离性
|
进程级
|
系统级(更彻底)
|
操作系统
|
主要支持Linux
|
几乎所有
|
封装程度
|
只打包项目代码和依赖关系 共享宿主机内核
|
完整的操作系统
|
docker应用场景
- 应用程序的打包和发布
- 应用程序隔离
- 持续集成
- 部署微服务
- 快速搭建测试环境
- 提供paas产品 平台服务
docker 安装
docker版本
- 社区版(Community Edition,CE)
- 企业版(Enterprise Edition,EE)
支持的平台
Linux CentOS,Debian,Fedora,Oracle Linux,RHEL,SUSE和Ubuntu
Windows
Mac
Centos7.x 安装dokcer
# 安装依赖包 yum install -y yum-utils device-mapper-persistent-data lvm2 # 添加Docker软件包源 yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo # 安装Docker CE yum install -y docker-ce # 启动Docker服务并设置开机启动 systemctl start docker systemctl enable docker
镜像管理
镜像是什么?
- 一个分层存储的文件
- 一个软件的环境
- 一个镜像可以创建N个容器
- 一种标准化的交付
- 一个不包含Linux内核而又精简的Linux操作系统
镜像不是一个单一的文件,而是有多层构成。我们可以通过docker history 查看镜像中各层内容及大小,每层对应着Dockerfile中的一条指令。Docker镜像默认存储在/var/lib/docker/\中。
镜像从哪里来?
Docker Hub是由Docker公司负责维护的公共注册中心,包含大量的容器镜像,Docker工具默认从这个公共镜像库下载镜像。
地址:https://hub.docker.com/explore
配置镜像加速器:https://www.daocloud.io/mirror
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io
镜像如容器的联系
如图,容器其实是在镜像的最上面加了一层读写层,在运行容器里文件改动时,会先从镜像里要写的文件复制到容器自己的文件系统中(读写层)。
如果容器删除了,最上面的读写层也就删除了,改动也就丢失了。所以无论多少个容器共享一个镜像,所做的写操作都是从镜像的文件系统中复制过来操作的,并不会修改镜像的源文件,这种方式提高磁盘利用率。若想持久化这些改动,可以通过docker commit 将容器保存成一个新镜像
镜像与容器的区别
- 一个镜像创建多个容器
- 镜像增量式存储
- 创建的容器里面修改不会影响到镜像
管理镜像常用命令
指令
|
描述
|
ls
|
列出镜像
|
build
|
构建镜像来自Dockerfile
|
history
|
查看镜像历史
|
inspect
|
显示一个或多个镜像详细信息
|
pull
|
从镜像仓库拉取镜像
|
push
|
推送一个镜像到镜像仓库
|
rm
|
移除一个或多个镜像
|
prune
|
移除未使用的镜像。没有被标记或被任何容器引用的。
|
tag
|
创建一个引用源镜像标记目标镜像
|
export
|
导出容器文件系统到tar归档文件
|
import
|
导入容器文件系统tar归档文件创建镜像
|
save
|
保存一个或多个镜像到一个tar归档文件
|
load
|
加载镜像来自tar归档或标准输入
|
容器管理
创建容器常用选项
选项
|
描述
|
-i, –interactive
|
交互式
|
-t, –tty
|
分配一个伪终端
|
-d, –detach
|
运行容器到后台
|
-e, –env
|
设置环境变量
|
-p, –publish list
|
发布容器端口到主机
|
-P, –publish-all
|
发布容器所有EXPOSE的端口到宿主机随机端口
|
–name string
|
指定容器名称
|
-h, –hostname
|
设置容器主机名
|
–ip string
|
指定容器IP,只能用于自定义网络
|
–network
|
连接容器到一个网络
|
–mount mount
|
将文件系统附加到容器
|
-v, –volume list
|
绑定挂载一个卷
|
–restart string
|
容器退出时重启策略,默认no,可选值:[always|on-failure]
|
容器资源限制
选项
|
描述
|
-m,–memory
|
容器可以使用的最大内存量
|
–memory-swap
|
允许交换到磁盘的内存量
|
–memory-swappiness=<0-100>
|
容器使用SWAP分区交换的百分比(0-100,默认为-1)
|
–oom-kill-disable
|
禁用OOM Killer
|
--cpus
|
可以使用的CPU数量
|
–cpuset-cpus
|
限制容器使用特定的CPU核心,如(0-3, 0,1)
|
–cpu-shares
|
CPU共享(相对权重)
|
管理容器常用命令
选项
|
描述
|
ls
|
列出容器
|
inspect
|
查看一个或多个容器详细信息
|
exec
|
在运行容器中执行命令
|
commit
|
创建一个新镜像来自一个容器
|
cp
|
拷贝文件/文件夹到一个容器
|
logs
|
获取一个容器日志
|
port
|
列出或指定容器端口映射
|
top
|
显示一个容器运行的进程
|
stats
|
显示容器资源使用统计
|
stop/start/restart
|
停止/启动一个或多个容器
|
rm
|
删除一个或多个容器
|
管理应用程序数据
将数据从宿主机挂载到容器中的三种方式
Docker提供三种方式将数据从宿主机挂载到容器中:
- volumes:Docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)。保存数据的最佳方式。
- bind mounts:将宿主机上的任意位置的文件或者目录挂载到容器中。
- tmpfs:挂载存储在主机系统的内存中,而不会写入主机的文件系统。如果不希望将数据持久存储在任何位置,可以使用tmpfs,同时避免写入容器可写层提高性能。
Volume
管理卷: # docker volume create nginx-vol # docker volume ls # docker volume inspect nginx-vol 用卷创建一个容器: # docker run -d --name=nginx-test --mount src=nginx-vol,dst=/usr/share/nginx/html nginx # docker run -d --name=nginx-test -v nginx-vol:/usr/share/nginx/html nginx 清理: # docker stop nginx-test # docker rm nginx-test # docker volume rm nginx-vol
注意:
1. 如果没有指定卷,自动创建。
2. 建议使用--mount,更通用。
https://docs.docker.com/storage/volumes/
Bind Mounts
用卷创建一个容器: # docker run -d -it --name=nginx-test --mount type=bind,src=/app/wwwroot,dst=/usr/share/nginx/html nginx # docker run -d -it --name=nginx-test -v /app/wwwroot:/usr/share/nginx/html nginx 验证绑定: # docker inspect nginx-test 清理: # docker stop nginx-test # docker rm nginx-test
注意:
1.如果源文件/目录没有存在如果挂载目标在容器中非空目录,则该目录现有内容将被隐藏。
2.不会自动创建,会抛出一个错误。
https://docs.docker.com/engine/admin/volumes/bind-mounts/#start-a-container-with-a-bind-mount
小结
Volume特点:
- 多个运行容器之间共享数据,多个容器可以同时挂载相同的卷。
- 当容器停止或被移除时,该卷依然存在。
- 当明确删除卷时,卷才会被删除。
- 将容器的数据存储在远程主机或其他存储上(间接)
- 将数据从一台Docker主机迁移到另一台时,先停止容器,然后备份卷的目录(/var/lib/docker/volumes/)
Bind Mounts特点:
- 从主机共享配置文件到容器。默认情况下,挂载主机/etc/resolv.conf到每个容器,提供DNS解析。
- 在Docker主机上的开发环境和容器之间共享源代码。例如,可以将Maven target目录挂载到容器中,每次在 Docker主机上构建Maven项目时,容器都可以访问构建的项目包。
- 当Docker主机的文件或目录结构保证与容器所需的绑定挂载一致时
容器网络
网络模式
- bridge–net=bridge默认网络,Docker启动后创建一个docker0网桥,默认创建的容器也是添加到这个网桥中。
- host–net=host容器不会获得一个独立的network namespace,而是与宿主机共用一个。这就意味着容器不会有自己的网卡信息,而是使用宿主机的。容器除了网络,其他都是隔离的。
- none–net=none获取独立的network namespace,但不为容器进行任何网络配置,需要我们手动配置。
- container–net=container:Name/ID与指定的容器使用同一个network namespace,具有同样的网络配置信息,两个容器除了网络,其他都还是隔离的。
- 自定义网络与默认的bridge原理一样,但自定义网络具备内部DNS发现,可以通过容器名容器之间网络通信。
容器网络访问原理
Dockerfile
Dockerfile格式
FROM centos:latest RUN yum install gcc -y COPY run.sh /usr/bin EXPOSE 80 CMD [“run.sh”] MAINTAINER lizhenliang
Dockerfile指令
指令
|
描述
|
FROM
|
构建新镜像是基于哪个镜像
|
LABEL
|
标签
|
RUN
|
构建镜像时运行的Shell命令
|
COPY
|
拷贝文件或目录到镜像中
|
ENV
|
设置环境变量
|
USER
|
为RUN、CMD和ENTRYPOINT执行命令指定运行用户
|
EXPOSE
|
声明容器运行的服务端口
|
HEALTHCHECK
|
容器中服务健康检查
|
WORKDIR
|
为RUN、CMD、ENTRYPOINT、COPY和ADD设置工作目录
|
ENTRYPOINT
|
运行容器时执行,如果有多个ENTRYPOINT指令,最后一个生效
|
CMD
|
运行容器时执行,如果有多个CMD指令,最后一个生效
|
Build镜像
Usage: docker build [OPTIONS] PATH | URL | - [flags] Options: -t, --tag list # 镜像名称 -f, --file string # 指定Dockerfile文件位置 # docker build -t shykes/myapp . # docker build -t shykes/myapp -f /path/Dockerfile /path # docker build -t shykes/myapp http://www.example.com/Dockerfile
构建Nginx,PHP,Tomcat基础镜像
- 构建Nginx基础镜像
FROM centos:7 LABEL wenlong RUN yum install -y gcc gcc-c++ make \ openssl-devel pcre-devel gd-devel \ iproute net-tools telnet wget curl && \ yum clean all && \ rm -rf /var/cache/yum/* RUN wget http://nginx.org/download/nginx-1.15.5.tar.gz && \ tar zxf nginx-1.15.5.tar.gz && \ cd nginx-1.15.5 && \ ./configure --prefix=/usr/local/nginx \ --with-http_ssl_module \ --with-http_stub_status_module && \ make -j 4 && make install && \ rm -rf /usr/local/nginx/html/* && \ echo "ok" >> /usr/local/nginx/html/status.html && \ cd / && rm -rf nginx-1.15.5* && \ ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime ENV PATH $PATH:/usr/local/nginx/sbin COPY nginx.conf /usr/local/nginx/conf/nginx.conf WORKDIR /usr/local/nginx EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]
- 构建PHP基础镜像
FROM centos:7 LABEL maintainer wenlong RUN yum install epel-release -y && \ yum install -y gcc gcc-c++ make gd-devel libxml2-devel \ libcurl-devel libjpeg-devel libpng-devel openssl-devel \ libmcrypt-devel libxslt-devel libtidy-devel autoconf \ iproute net-tools telnet wget curl && \ yum clean all && \ rm -rf /var/cache/yum/* RUN wget http://docs.php.net/distributions/php-5.6.36.tar.gz && \ tar zxf php-5.6.36.tar.gz && \ cd php-5.6.36 && \ ./configure --prefix=/usr/local/php \ --with-config-file-path=/usr/local/php/etc \ --enable-fpm --enable-opcache \ --with-mysql --with-mysqli --with-pdo-mysql \ --with-openssl --with-zlib --with-curl --with-gd \ --with-jpeg-dir --with-png-dir --with-freetype-dir \ --enable-mbstring --with-mcrypt --enable-hash && \ make -j 4 && make install && \ cp php.ini-production /usr/local/php/etc/php.ini && \ cp sapi/fpm/php-fpm.conf /usr/local/php/etc/php-fpm.conf && \ sed -i "90a \daemonize = no" /usr/local/php/etc/php-fpm.conf && \ mkdir /usr/local/php/log && \ cd / && rm -rf php* && \ ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime ENV PATH $PATH:/usr/local/php/sbin COPY php.ini /usr/local/php/etc/ COPY php-fpm.conf /usr/local/php/etc/ WORKDIR /usr/local/php EXPOSE 9000 CMD ["php-fpm"]
- 构建Tomcat基础镜像
FROM centos:7 LABEL maintainer wenlong ENV VERSION=8.0.52 RUN yum install java-1.8.0-openjdk wget curl unzip iproute net-tools -y && \ yum clean all && \ rm -rf /var/cache/yum/* RUN wget http://mirrors.shu.edu.cn/apache/tomcat/tomcat-8/v${VERSION}/bin/apache-tomcat-${VERSION}.tar.gz && \ tar zxf apache-tomcat-${VERSION}.tar.gz && \ mv apache-tomcat-${VERSION} /usr/local/tomcat && \ rm -rf apache-tomcat-${VERSION}.tar.gz /usr/local/tomcat/webapps/* && \ mkdir /usr/local/tomcat/webapps/test && \ echo "ok" > /usr/local/tomcat/webapps/test/status.html && \ sed -i '1a JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom"' /usr/local/tomcat/bin/catalina.sh && \ ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime ENV PATH $PATH:/usr/local/tomcat/bin WORKDIR /usr/local/tomcat EXPOSE 8080 CMD ["catalina.sh", "run"]
快速搭建LNMP网站平台
1、自定义网络 docker network create lnmp 2、创建Mysql容器 docker run -d \ --name lnmp_mysql \ --net lnmp \ --mount src=mysql-vol,dst=/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=wordpress mysql:5.7 --character-set-server=utf8 3、创建PHP容器 docker run -d --name lnmp_php --net lnmp --mount src=wwwroot,dst=/wwwroot php:v1 4、创建Nginx容器 docker run -d --name lnmp_nginx --net lnmp -p 88:80 \ --mount src=wwwroot,dst=/wwwroot nginx:v1 5、以wordpress博客为例 https://cn.wordpress.org/wordpress-4.9.4-zh_CN.tar.gz