一、概述
1、容器介绍
Linux中的容器是装应用的,容器就是将软件打包成标准化单元,用于开发、交付和部署,容器技术已成为应用程序封装和交付的核心技术。
1.1、容器组成
容器技术的核心有以下几个内核技术组成:
—Cgroups(Control Groups)资源管理:实现对资源的配额和度量
—SELinux安全
—NameSpace-命名空间:实现Container的进程、网络、消息、文件系统和主机名的隔离
—Linux的NameSpace:UTS、NETWORK、MOUNT、USER、PID、IPC
1.2、容器优、缺点
- 优点
快、小:比虚拟机小,比虚拟机快,管理操作(启动、停止、开始重启等等)都是以秒或亮秒为单位。
敏捷:像虚拟机一样敏捷,而且全更便宜,在bare metal(裸机)上布置像点个按钮一样简单
灵活:将应用和系统“容器化”,不添加额外的操作系统
轻量:你会拥有足够的“操作系统”,仅需 添加或减小镜像即可。
便宜:开发人员并不关心具体哪个Linux操作系统,相比于传统的虚拟化技术,容器更加简洁高效。传统虚拟机需要给每个VM安装操作系统。容器使用的共享公共库和程序。
- 缺点:
数据:Docker部署应用的时候,并不包含数据,一般挂载到外部。
隔离:容器的隔离性没有虚拟化强。
安全:共用Liunx内核,安全性有先天缺陷。最好做一个分布式的部署来避免出现主机故障影响正常服务。
2、docker介绍
2.1、docker与容器的关系
Docker是一套容器管理系统,可以提供一组命令,让用户更加方便直接使用容器技术,而不需要过多关心底层内核技术。Docker 是管理容器的工具, Docker 不等于 容器。
- 容器管理进程,上帝进程
容器的启动进程就是上帝进程,上帝进程的pid == 1,上帝进程退出==容器关闭。上帝进程简单的说就是系统创建之初产生的第一个进程。
- 上帝进程的特点
没有父进程,PID == 1,所有进程都是他的子进程、孙子进程……,上帝进程死亡系统实例也就不存在了。
- 容器的管理
容器的启动进程(上帝进程)不能被关闭,容器的启动进程必须在前台运行。
- 容器的启动服务
前台服务/后台服务:容器的启动进程在后台运行≠容器在后台运行
前台服务 (-it):一般能与用户交互的程序,比如/bin/bash、/bin/sh等
后台服务 (-itd):一般是一个程序服务 ,比如 apache、nginx、redis等
二、docker安装
1、相关信息
- Docker中国官方网站:
https://docs.docker.com/registry/recipes/mirror///use-case-the-china-registry-mirror+(Official lmage官方标志)
- 阿里云的镜像仓库:
https://help.aliyun.com/document_detail/60750.html
- /etc/docker/daemon.json文件添加如下内容
{ "registry-mirrors": ["<your accelerate address>"]}
2、部署过程
- docker yum源设置
[root@node1 ~]# wget https://download.docker.com/linux/centos/docker-ce.repo -P /etc/yum.repos.d/
[root@node1 ~]# sed -i 's#download.docker.com#mirrors.tuna.tsinghua.edu.cn/docker-ce#g' /etc/yum.repos.d/docker-ce.repo
- 卸载旧版本
[root@node1 ~]# yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
- 开启路由转发
[root@node1 ~]# vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
[root@node1 ~]# sysctl -p
[root@node1 ~]# systemctl restart network
- 安装docker
[root@node1 ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
[root@node1 ~]# yum -y install docker-ce
- 启动docker并验证
[root@node1 ~]# systemctl enable docker
[root@node1 ~]# systemctl start docker
[root@node1 ~]# systemctl status docker
[root@node1 ~]# docker -v
[root@node1 ~]# ifconfig # 验证,能看见 docker0
[root@node1 ~]# docker version # 验证,没有报错
3、docker client 和 daemon分离
- 关闭docker
[root@node1 ~]# systemctl stop docker
- 修改docker启动方式,要求加载配置文件启动
[root@node1 ~]# sed -i.bak '/^ExecStart=/c\ExecStart=\/usr\/bin\/dockerd' /usr/lib/systemd/system/docker.service
- 设置docker配置文件,默认没有
[root@node1 ~]# cat /etc/docker/daemon.json
{
"hosts": ["tcp://0.0.0.0:2375","unix:///var/run/docker.sock"]
}
[root@node1 ~]# systemctl daemon-reload
[root@node1 ~]# systemctl restart docker
[root@node1 ~]# yum -y install net-tools
[root@node1 ~]# netstat -ntulp | grep 2375
[root@node1 ~]# docker -H 192.168.4.10 miages #验证
三、管理命令
镜像概述:镜像是启动容器的核心,在Docker中容器是基于镜像启动的,镜像采用分层设计,使用COW技术。
如何获取镜像:镜像可以从官方镜像仓库https://hub.docker.com下载,也可以自己制作。
1、镜像管理
命 令 | 作 用 | 案 例 |
docker images | 查看本地存储的镜像 | |
docker search 镜像名称 | 镜像搜索,从docker镜像仓库模糊搜索镜像 字段说明: NAME:镜像名称 | docker search nginx |
docker pull 镜像名 | 拉取镜像 ,从docker指定的仓库下载镜像到本地 | docker pull nginx |
docker push 镜像名:标签 | 上传镜像,把镜像从本地上传到仓库,镜像名要改成仓库地址/镜像名 | |
docker inspect [镜像名称或者ID] | 显示镜像的详细导入由save保存出来的压缩文件镜像,查看镜像的详细信息Env、Cmd下面的内容 | docker inspect centos |
docker history 镜像名称:标签 | 查看镜像的制作历史 | |
docker rmi [镜像名称或者ID] | 删除本地镜像库中的某个镜像(必须先删除该镜像启动的所有容器) | docker rmi centos:latest |
docker save -o 压缩文件名称 [镜像名称或者ID] | 存镜像与压缩文件 | docker save -o centos_base.tar centos |
docker load -i 镜像压缩文件名称 [镜像名称或者ID] | 导入由save保存出来的压缩文件镜像 | |
docker tag 镜像名称:标签 新的镜像称:新的标签 | 创建新的镜像名称和标签 | docker tag centos:latest myos:latest |
2、容器管理
命 令 | 作 用 | 案 例 |
docker run [选项] 镜像名称 启动命令 | run:容器创建、启动、进入容器, 选项: -i:交互式创建 --rm:容器在启动后执行完成命令会自动销毁 -启动命令:/bin/bash在终端中执行的命令,容器内的执行程序 | docker run -it centos:latest /bin/bash |
docker ps [-a :所有容器的ID] [-q :只显示容器id] | 查看容器的状态 | docker ps |
docker rm 容器ID | 删除容器 | 命令技巧: docker rm $(docker ps -aq) |
docker create 镜像文件 | create:创建一个新的容器,但不启动容器,状态为Created,通过docker ps -a可以查看 | docker create nginx |
docker cp 源文件 目标地址 | cp:从容器中拷贝指定文件或者目录到宿主机中,也可以从宿主机上传文件到容器中 上传:从宿主机上传到容器内 docker cp 本机的文件路径 容器ID:容器内路径 下载:从容器内下载到宿主机 docker cp 容器ID:容器内路径 本机文件路径 | docker cp nginx:/etc/passwd /tmp/ docker cp /etc/hosts nginx:/root/ |
docker diff [容器名或ID] | diff:查看docker容器变化。 | docker diff nginx |
docker ps [-a:所有容器] [-q:只显示容器的id] | 容器查看-ps命令,显示运行中的容器,加上命令选项-a,包含关闭的容器,所有本地容器列表都会显示。 | docker ps -aq |
docker inspect [容器名称或者ID] | 查看容器信息,容器详细信息-inspect命令,显示容器的详细信息 | docker inspect centos:latest |
docker rm [容器名称或者ID] [-force:强制删除一个运行中的容器] | 容器删除-rm命令,删除一个本地容器 | docker rm loving_bhaskara |
docker exec -it 容器id 启动命令 | 容器执行命令-exec命令,进入容器,启动新进程,退出后容器不会关闭(主要用于维护管理) | docker exec -it centos /bin/bash |
docker attach [容器名称或者ID] | 容器信息输出-attach命令,连接容器启动进程(主要用于排错) 进入容器的默认进程,退出后容器会关闭: docker attach 容器id 进入容器以后,退出容器而不关闭容器的方法: docker attach 容器id [ctrl+p, ctrl+q] | docker attach centos |
docker start|stop|restart 容器ID | 启动、停止、重启容器管理命令start|stop|restart | docker start centos docker stop centos docker stop $(docker ps -aq) |
docker pause [容器名称或者ID] | 容器挂起-pause命令,暂停容器,挂起运行中的容器 | docker pause centos |
docker unpause [容器名称或者ID] | 容器恢复-unpause命令,恢复挂起容器 | docker unpause centos |
docker rename 容器名称 容器新名称 | 容器重命名-rename命令,重命名容器 | docker rename centos centos_8 |
docker port [容器名称或者ID] | 容器端口映射信息-port命令,显示容器与宿主机的端口隐射信息 | docker port eager_lamport |
docker kill [镜像名称或者ID] | 杀死一个或多个容器-kill命令,杀死运行的容器 | docker kill eager_lamport |
docker export -o 导出后镜像文件名 [容器名称或者ID] | 容器导出-export命令,将一个容器导出一个镜像为压缩文件 | docker export -o centos.tar centos_8 |
docker commit [容器名称或者ID] 导出后镜像的名字:tag | 将容器生成镜像-commit命令,将改变后的容器直接变成镜像,一般指的是封装好业务的容器,直接封装成镜像 | docker commit centos_8 centos_9:latest |
docker stats 容器名称 | stats:显示一个存活容器的资源使用情况。 | docker stats nginx |
docker top 容器名称 | top:查看容器中运行的进程信息。 | docker top nginx |
docker update [容器配置] [配置更新参数] 容器名称 | update 命令可以用于更新一个或多个 Docker 容器的配置。 | docker update -m 512M haicoder |
docker logs 容器id --参数 | 查看指定容器的日志 参数: --since= "时间" ,查看指定时间之后的日志。 -f:查看实时日志 -t:查看日志产生的日期 -tail=10:查看最后的10条日志 | |
docker import 镜像文件名 镜像名:tag | 容器镜像导入到镜像库-import命令:将容器镜像导入到镜像库。 docker load命令导入镜像库存储文件到本地镜像库;docker import命令导入一个容器快照到本地镜像库。 容器快照将会丢弃所有的历史记录和元数据信息,而镜像存储文件将保存完整记录,体积也会更大。 |
- 其它命令:
version:查看docker版本号。
network:管理Docker网络。
swarm:管理Docker Swarm。
node:管理DockerSwarm节点。
volume:管理Docker卷。
build:通过Dockerfile定制镜像,详情看:Docker:使用Dockerfile构建Nginx镜像。
四、镜像制作
docker镜像应该遵循的原则:1、镜像最小化原则;需要选择最精简的基础镜像、清理镜像构建的中间产物、减少镜像的层数。2、构建速度最快化原则;充分利用镜像构建缓存,再利用构建的缓存来加快镜像构建速度。3、注意优化网络请求。
1、docker commit
通过docker commit
命令,基于一个已存在的容器构建出镜像,自定义镜像原理:镜像采用分层设计,创建读写层,修改配置,重新打包
- commit打包镜像格式:docker commit 容器id或容器名称 新镜像名称:标签
1.1、案例
创建读写层
docker run -itd --name centos docker.io/centos:latest
查看容器ID
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
267b68a29358 docker.io/centos:latest "/bin/bash" 3 seconds ago Up 2 seconds centos
进入容器,修改配置
docker exec -it 267b68a29358 bash
[root@267b68a29358 /]# mkdir abc
[root@267b68a29358 /]# vi abc/1
[root@267b68a29358 /]# exit
exit
暂停容器运行
docker pause centos
重新打包镜像
docker commit centos centos:v1.10
查看构建镜像
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos v1.10 d1672459bb68 39 seconds ago 231 MB
1.2、commit命令构建镜像总结
使用docker commit构建的镜像包含了编译构建、安装软件,以及程序运行产生的大量无用文件,这会导致镜像体积很大,非常臃肿。使用docker commit构建的镜像会丢失掉所有对该镜像的操作历史,无法还原镜像的构建过程,不利于镜像的维护。
除了以下这两种场景,不建议使用docker commit来构建生产现网环境的镜像。
- 适用场景
构建临时的测试镜像;
容器被入侵后,使用docker commit,基于被入侵的容器构建镜像,从而保留现场,方便以后追溯。
2、Dockerfile
docker build命令会读取Dockerfile的内容,并将Dockerfile的内容发送给 Docker 引擎,最终 Docker 引擎会解析Dockerfile中的每一条指令,构建出需要的镜像。
- Dockerfile语法解析:
commit的局限:很容易制作简单的镜像,但碰设置默认的命令、环境变量和指定镜像开放某些特定的端口就十分不方便。
Dockerfile是一种更强大的镜像制作方式,编写类似脚本的Dockerfile文件,通过该文件制作镜像。
- Dockerfile的命令:
FROM:指定基础镜像,使用格式:FROM 镜像名称:版本号
RUN:制作镜像时执行的命令,可以有多个
ADD:复制文件到镜像,自动解压(比copy高级,可以自动下载网络网文件)
COPY:复制文件到镜像,不解压
EXPOSE:声明开放的端口
ENV:设置容器启动后的环境变量
WORKDIR:远程时cd失效,定义容器默认工作目录(等于cd)
CMD:容器启动时执行的命令,仅可以有一条CMD
MAINTAINER:提供Dockerfile制作者本人信息,使用格式:MAINTANIER “内容”
- Dockerfile的文件创建镜像:docker build -t 镜像名称:标签 Dockerfile所在目录
2.1、案例
创建存储Dockerfile的目录
mkdir apache
cd apache/
创建Dockerfile文档
vim Dockerfile
FROM docker.io/centos:latest
RUN rm -rf /etc/yum.repo.d/*
ENV LANG=C
ADD webhome.tar.gz /var/www/html
WORKDIR /var/www/html
EXPOSE 80
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
备注:
— CMD指令可以查看 service 文件的启动命令 ExecStart(/lib/systemd/system/httpd.service)
— ENV环境变量查询服务文件中的环境变量配置文件 EnvironmentFile 指定的文件内容
3、save和load
docker save用来将镜像保存为一个 tar 文件,docker load用来将 tar 格式的镜像文件加载到当前机器上。
3.1、案例
save命令将镜像保存为一个tar文件
docker save -o centos.tar centos:v1.10
load将tar格式的镜像导入到本地
docker load -i centos.tar
4、export和import
通过docker export 保存容器的镜像,再通过docker import 加载镜像。
4.1、案例
export命令将容器保存为tar文件
docker export -o httpd.tar d35f93b70a8b
import命令将tar格式的镜像导入到本地
docker import - httpd:v1.12 httpd.tar
4.2、总结
通过docker export导出的镜像和通过docker save保存的镜像相比,会丢失掉所有的镜像构建历史。在实际生产环境中,不建议通过docker save和docker export这两种方式来创建镜像。较推荐的方式是:在 A 机器上将镜像 push 到镜像仓库,在 B 机器上从镜像仓库 pull 该镜像。
五、微服务架构
1、介绍
它是一种架构模式,提供将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。有别于更为传统的单体式方案,将应用拆分成多个核心功能,可以单独构建和部署。它不只是应用核心功能间的这种松散耦合,还涉及如何进行服务间通信以应对不可避免的故障、满足未来的可扩展性并实现新的功能集成。它解决了复杂性问题。将单体应用分解为一组服务。虽然功能总量不变,但应用程序已被分解为可管理的模块或服务,这种体系结构使得每个服务都可以独立开发、运行,降低了服务的耦合性更适合CI/CD。
- 微服务的优点:高度可扩展、出色的弹性、易于部署、易于访问、更易开发,松耦合高内聚
微服务的核心就是“拆”,要想构建服务就要理清各个服务之间的关系,保持服务的持续演进,使服务能够快速、低成本地被拆分和合并,以快速响应业务的变化,执续迭代。
docker这种应用的管理模式正是微服务的思想,每个容器承载一个服务。一台计算机同时运行多个容器,从而就能很轻松地模拟出复杂的微服务架构。
2、案例
2.1、制作php-fpm镜像
创建目录
mkdir php && cd php
编写Dockerfile文件
cat Dockerfile
FROM docker.io/centos:latest
RUN yum install -y php-fpm && yum clean all
EXPOSE 9000
CMD ["/usr/sbin/php-fpm", "--nodaemonize"]
构建php-fpm镜像
docker build -t php-fpm:v1.10 .
验证 php-fpm服务
docker run -itd --name php-fpm php-fpm:v1.10
docker exec -it php-fpm bash
ss -ltun
2.2、制作 nginx镜像
制作nginx软件包
yum install -y gcc make pcre-devel openssl-devel
useradd nginx
tar -zxvf nginx-1.12.2.tar.gz
cd nginx-1.12.2/
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module
make && make install
mv info.php info.html /usr/local/nginx/html/
cd /usr/local/
tar czf nginx.tar.gz nginx
创建目录
mkdir nginx && cd nginx
nignx软件包放到nignx目录下,和Dockerfile文件存储在一起
cp /usr/local/nginx.tar.gz ./
编写Dockerfile文件
cat Dockerfile
FROM docker.io/centos:latest
RUN yum install -y pcre openssl && useradd nginx && yum clean all
ADD nginx.tar.gz /usr/local/
EXPOSE 80
WORKDIR /usr/local/nginx/html
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
说明:
Dockerfile中ADD可以将一个压缩包在容器内解压释放 ,利用这一特性,在外部编译nginx,并把编译好的文件打包,使用打包文件构建nginx镜像服务,nginx进程默认在后台运行,可以使用参数daemon off,强制进程在前台运行。
构建nginx镜像
docker build -t nginx:v1.10 .
服务验证
docker run -itd -p 8080:80 --name nginx nginx:v1.10
netstat -na | grep 8080
curl 192.168.65.11:8080
curl 192.168.65.11:8080/info.html
3、发布容器服务
3.1、如何访问容器服务?
默认容器可以访问外网,但外部网络的主机不可以访问容器内的资源,容器每次创建IP地址都会改变,解决这个问题的最佳方法就是端口绑定,容器可以与宿主机的端口进行绑定,从而把宿主机变成对应的服务,不用关心容器的IP地址。
3.2、发布web服务
使用-p参数把容器端口和宿主机端口绑定,同一宿主机端口只能绑定一个容器服务。
- 端口绑定命令:-p[可选IP]:宿主机端口:容器端口(可有多个端口)
- 例:
docker run -itd -p 80:80 myos:httpd #把宿主机变成apache
docker run -itd -p 80:80 myos:nginx #把宿主机变成nginx