一.为什么使用容器?
1.上线流程繁琐
开发->测试->申请资源->审批->部署->测试等环节
2.资源利用率低
普遍服务器利用率低,造成过多浪费
3.扩容/缩容不及时
业务高峰扩容流程繁琐,上线不及时
已知情况,例如618,双11
未知情况,业务机器增加承载量,可以应对一些突发,一般预留30%的配置
-弹性伸缩
4.服务器环境臃肿
服务器越来越臃肿,对维护,迁移带来困难
5.环境不一致性
进一步对比
虚拟机:
1.提升服务器资源利用率
2.提供一个完全隔离的环境
容器:
1.容器提供一个基本的独立环境,实现容器隔离,资源限制
2.主要解决应用层问题,应用快速部署,高效管理
三.Docker是什么
1.使用最广泛的开源容器引擎
2.一种操作系统级的虚拟话技术
3.依赖于Linux内核特性:Namespace(资源隔离)和Cgroups(资源限制)
4.一个简单的应用程序打包工具
设计目标
1.提供简单的应用程序打包
2.开发人员和运维人员职责逻辑分离
3.多环境保持一致性
(设计来源集装箱)
运行起来,互不影响
开发人员:
1.开发项目
2.打包项目环境+代码成镜像
3.部署到容器平台
运维人员:怎么高效的去管理这些容器
好处:
1.运维人员节省人工成本
2.持续发布有问题更快解决
Docker应用场景
1.应用程序打包和发布
2.应用程序隔离
3.持续集成
4.部署微服务
5.快速搭建测试环境
6.提供PasS产品(平台即服务)
3.Docker基本组成
Docker Client:Linux命令行执行的客户端命令,Docker命令
Host:Docker主机
Docker Registry:Docker镜像
4.版本与支持平台
Docker版本:
1.社区版(Community Edition,CE)
2.企业版(Enterprise Edition,EE)
支持平台:
1.Linux(CentOS,Debian,Fedora,Oracle Linux,RHEL,SUSE和Ubuntu)
2.Mac
3.Windows
官方文档:
https://docs.docker.com/engine/install/centos/
四.Docker安装
第一步:安装前建议关闭selinux和firewalld NetworkManager
#关闭firewalld 和NetworkManager
[root@D ~]#systemctl stop firewalld NetworkManager
[root@D ~]#systemctl disable firewalld NetworkManager
检查是否正在运行
systemctl is-active firewalld NetworkManager
检查是否开机自启动
systemctl is-enabled firewalld NetworkManager
[root@D ~]# systemctl is-active firewalld NetworkManager crond
unknown
inactive
active
[root@D ~]# systemctl is-enabled firewalld NetworkManager crond
disabled
disabled
enabled
关闭selinux
cat /etc/selinux/config
[root@D ~]# grep =disable /etc/selinux/config
SELINUX=disabled
[root@D ~]# setenforce 0
[root@D ~]# getenforce
Permissive
安装docker
第二步:安装好系统,卸载系统内老的docker版本
[root@docker ~]# yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
第三步:安装依赖包
默认没有docker源
[root@docker01 ~]# cd /etc/yum.repos.d/
[root@docker01 /etc/yum.repos.d]# ls
CentOS-Base.repo CentOS-Sources.repo
CentOS-CR.repo CentOS-Vault.repo
CentOS-Debuginfo.repo CentOS-x86_64-kernel.repo
CentOS-fasttrack.repo epel.repo
CentOS-Media.repo
为其配置一个稳定的docker源
[root@docker01 ~]# yum install -y yum-utils
[root@docker01 ~]# yum-config-manager \ --add-repo \ [https://download.docker.com/linux/centos/docker-ce.repo]
[root@docker01 /etc/yum.repos.d]# ls (配置完毕会出现一个docker-re.repe文件)
CentOS-Base.repo CentOS-Media.repo docker-ce.repo
CentOS-CR.repo CentOS-Sources.repo epel.repo
CentOS-Debuginfo.repo CentOS-Vault.repo
CentOS-fasttrack.repo CentOS-x86_64-kernel.repo
第四步:安装docker-ce
[root@docker01 ~]# yum install -y docker-ce
[root@docker01 ~]# systemctl start docker
[root@docker01 ~]# systemctl enable docker
第五步:验证是否启动成功(几种验证方法)
[root@docker01 ~]# docker version
[root@docker01 ~]# docker info
[root@docker01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
官方文档:https://docs.docker.com
阿里云源:http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
五.Docker镜像管理
• 镜像是什么?
• 配置加速器
• 镜像常用管理命令
1.镜像是什么?
• 一个分层存储的文件,不是一个单一的文件
• 一个软件的环境
• 一个镜像可以创建N个容器
• 一种标准化的交付
• 一个不包含Linux内核而又精简的Linux操作系统
2.配置加速器
Docker Hub是由Docker公司负责维护的公共镜像仓库,包含大量的容器镜像,Docker工具默认
从这个公共镜像库下载镜像。地址:https://hub.docker.com
为什么配置加速器,举个简单的例子:
[root@docker01 ~]# docker run -d nginx
Unable to find image 'nginx:latest' locally #本地找不到nginx镜像包
配置镜像加速器:
[root@docker01 ~]# vi /etc/docker/daemon.json
[root@docker01 ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
}
[root@docker01 ~]# systemctl restart docker
3.常用管理命令
命令格式:docker image COMMAND
查看本地有哪些镜像
[root@docker01 ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 519e12e2a84a 5 hours ago 133MB
查看镜像的构建过程
[root@docker01 ~]# docker history nginx
IMAGE CREATED CREATED BY SIZE COMMENT
519e12e2a84a 5 hours ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon… 0B
5 hours ago /bin/sh -c #(nop) STOPSIGNAL SIGQUIT 0B
5 hours ago /bin/sh -c #(nop) EXPOSE 80 0B
5 hours ago /bin/sh -c #(nop) ENTRYPOINT ["/docker-entr… 0B
5 hours ago /bin/sh -c #(nop) COPY file:09a214a3e07c919a… 4.61kB
5 hours ago /bin/sh -c #(nop) COPY file:0fd5fca330dcd6a7… 1.04kB
5 hours ago /bin/sh -c #(nop) COPY file:0b866ff3fc1ef5b0… 1.96kB
5 hours ago /bin/sh -c #(nop) COPY file:65504f71f5855ca0… 1.2kB
5 hours ago /bin/sh -c set -x && addgroup --system -… 63.8MB
5 hours ago /bin/sh -c #(nop) ENV PKG_RELEASE=1~buster 0B
5 hours ago /bin/sh -c #(nop) ENV NJS_VERSION=0.5.3 0B
5 hours ago /bin/sh -c #(nop) ENV NGINX_VERSION=1.19.9 0B
5 hours ago /bin/sh -c #(nop) LABEL maintainer=NGINX Do… 0B
11 hours ago /bin/sh -c #(nop) CMD ["bash"] 0B
11 hours ago /bin/sh -c #(nop) ADD file:c855b3c65f5ba94d5… 69.3MB
查看镜像的详细信息
[root@docker01 ~]# docker inspect nginx
从hub仓库下载一个镜像
[root@docker01 ~]# docker pull redis
删除镜像
[root@docker01 ~]# docker rmi 7f33e76fcb56
Untagged: redis:latest
Untagged: redis@sha256:7ff49b5e96de6e4472664591866bf4bb8d52eecf1405e8b2e16b49237dbee4c4
Deleted: sha256:7f33e76fcb56c96639cd127aca5f6cb61c526c3c6013048f637c32e863b7b012
Deleted: sha256:072f491f6aa3d8fd4171edb8cf967a690e152d263fc9ee96a5451807004e5b87
Deleted: sha256:b74e939adc897204e67f7b9590f50945bdfd665472adfaefa886113200e3c75d
Deleted: sha256:3f869c3604694dfd4d78a73f2374f835d10d8158b18b62fcf1aa32bb89457879
Deleted: sha256:b9735bc171046d655ce1bec3d81f83770ce81522165e26b25957dcb2fdc66d88
Deleted: sha256:42e8693cf8594736a7783ba70093f158c9155c07c7e0bf1c66d063d961b1d1e5
Deleted: sha256:346fddbbb0ff19bdb026afb053df490c0c73981a8a985882cf8ee3d716735e87
移除没有被标记的镜像
[root@docker01 ~]# docker image prune
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B
[root@docker01 ~]# docker image prune -a
WARNING! This will remove all images without at least one container associated to them.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B
导出一个镜像
[root@docker01 ~]# docker save redis -o redis.tar
[root@docker01 ~]# ls
anaconda-ks.cfg redis.tar
[root@docker01 ~]# scp -r redis.tar [email protected]:~ (推送到没有网络的服务器)
导入一个镜像
[root@docker02 ~]# docker load -i redis.tar (导入到本地仓库)
六.创建容器常用选项
命令格式:docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
选项 | 描述 |
---|---|
-i, –interactive | 交互式 |
-t, –tty | 分配一个伪终端 |
-d, –detach | 运行容器到后台 |
-e, –env | 设置环境变量 |
-p, –publish list | 发布容器端口到主机 |
-P, –publish-all | 发布容器所有EXPOSE的端口到宿主机随机端口 |
--name string | 指定容器名称 |
-h, –hostname | 设置容器主机名 |
--ip string | 指定容器IP,只能用于自定义网络 |
--network | 连接容器到一个网络 |
-v, –volume list --mount mount(新方式) ) | 将文件系统附加到容器 |
--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共享(相对权重) |
1.使用exec 进入交互式终端,让进行夯住,让他一直运行
[root@docker01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d4007ba6d6da nginx "/docker-entrypoint.…" 50 minutes ago Up 50 minutes 0.0.0.0:8080->80/tcp inspiring_brahmagupta
[root@docker01 ~]# docker exec -it d4007ba6d6da bash
root@d4007ba6d6da:/# exit
使用-d参数,让容器运行到后台,不使用的话会在当前终端给输出出来
![image.png](https://upload-images.jianshu.io/upload_images/17001435-cb448ff128685789.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
正常都会加-d
[root@docker01 ~]# docker run -d nginx
2.测试-d -p -e --name --restart=always参数
[root@docker01 ~]# docker run -d -e env=prod -p 88:80 --name web -h web --restart=always nginx
600d94998f1b212f2736eb593ccd1cf2db0da672a40fd53fedc22fc335423f50
[root@docker01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
600d94998f1b nginx "/docker-entrypoint.…" 13 seconds ago Up 12 seconds 0.0.0.0:88->80/tcp web
测试效果
[root@docker01 ~]# docker exec -it web bash
root@web:~# hostname
web
root@web:~# echo $env
prod
root@web:/# cd /usr/share/nginx/html/
root@web:/usr/share/nginx/html# echo "wangwenbin DSB" > index.html
3.限制内容和cpu
[root@docker01 ~]# docker run -d -m="500m" --cpus="1" -d nginx
628440e526f18c03cfde4d42bf9a715fb4bf0d9b2f2e4186feb247ee1846ab24
七.常用管理命令
命令格式:docker container COMMAND
选项 | 描述 |
---|---|
ls | 列出容器 |
inspect | 查看一个或多个容器详细信息 |
exec | 在运行容器中执行命令 |
commit | 创建一个新镜像来自一个容器 |
cp | 拷贝文件/文件夹到一个容器 |
logs | 获取一个容器日志 |
port | 列出或指定容器端口映射 |
top | 显示一个容器运行的进程 |
stats | 显示容器资源使用统计 |
stop/start/restart | 停止/启动一个或多个容器 |
rm | 删除一个或多个容器 |
prune | 移除已停止的容器 |
1.列出容器
[root@docker01 ~]# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
600d94998f1b nginx "/docker-entrypoint.…" 48 minutes ago Up 48 minutes 0.0.0.0:88->80/tcp web
[root@docker01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
600d94998f1b nginx "/docker-entrypoint.…" 50 minutes ago Up 50 minutes 0.0.0.0:88->80/tcp we
2.列出最新创建出的容器
[root@docker01 ~]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
628440e526f1 nginx "/docker-entrypoint.…" 17 minutes ago Up 17 minutes 80/tcp crazy_grothendieck
3.使用exec在容器中运行命令
[root@docker01 ~]# docker exec -it web/id bash
4.使用commit将已经构建好的镜像打包到本地仓库中,进行使用
[root@docker01 ~]# docker commit web test
sha256:13430bc4a39b20ea6d7b30f63ead1ae43d25dc686a90e407bf8bb2704f1cbf79
[root@docker01 ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
test latest 13430bc4a39b 7 seconds ago 133MB
5.将宿主机的某个文件复制到容器中
[root@docker01 ~]# docker cp redis.tar web:/
[root@docker01 ~]# docker exec web ls
redis.tar
6.查看容器日志,做故障排查
[root@docker01 ~]# docker logs web
7.查看容器端口
[root@docker01 ~]# docker port web
80/tcp -> 0.0.0.0:88
查看容器中运行的进程
[root@docker01 ~]# docker top web
UID PID PPID C STIME TTY TIME CMD
root 16393 16374 0 22:13 ? 00:00:00 nginx: master process nginx -g daemon off;
101 16457 16393 0 22:13 ? 00:00:00 nginx: worker process
8.显示容器的资源利用率
默认不加--no-stream,会循环显示
[root@docker01 ~]# docker stats web --no-stream
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
600d94998f1b web 0.00% 2.125MiB / 1.934GiB 0.11% 17.5kB / 10.7kB 717kB / 6.14kB 2
写脚本使可配合使用
[root@docker01 ~]# docker stats web --no-stream |awk '{print $2}'
ID
web
9.清除已经退出的容器
[root@docker01 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fed8be8802fe centos "/bin/bash" 16 seconds ago Exited (0) 15 seconds ago blissful_ritchie
[root@docker01 ~]# docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
fed8be8802fe69930a65aaea86c8725071ac9d5449f54a76c12259ec1b918878
Total reclaimed space: 0B
docker ps 参数
-a 显示所有容器(运行和不运行都显示)
-q显示所有容器的id
[root@docker01 ~]# docker ps -q
628440e526f1
10.删除所有容器
[root@docker01 ~]# docker rm -f `docker ps -aq`
b83214d78f78
[root@docker01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
11.启动,停止,重启容器
[root@docker01 ~]# docker run -d -p 80:80 nginx
beb79803c08700a94575590547b1f9fac83cb425b2733b7dc7cb4620f9afe068
[root@docker01 ~]# docker stop eloquent_dhawan
eloquent_dhawan
[root@docker01 ~]# docker start eloquent_dhawan
eloquent_dhawan
[root@docker01 ~]# docker restart eloquent_dhawan
eloquent_dhawan
12.删除
[root@docker01 ~]# docker rm eloquent_dhawan
eloquent_dhawan
八.容器数据持久化
1.Docker提供三种方式将数据从宿主机挂载到容器中:
• volumes:Docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)。
保存数据的最佳方式。
• bind mounts:将宿主机上的任意位置的文件或者目录挂载到容器中。
1.volumes示例:
1、创建数据卷
# docker volume create nginx-vol #创建好的数据卷在/var/lib/docker/volumes
# docker volume ls #查看
# docker volume inspect nginx-vol #查看详细信息
2、使用数据卷
# docker run -d --name=nginx-test --mount src=nginxvol,dst=/usr/share/nginx/html nginx
# docker run -d --name=nginx-test -v nginxvol:/usr/share/nginx/html nginx
2.bind mounts示例:
1、挂载宿主机目录到容器
# docker run -d --name=nginx-test --mount type=bind,src=/app/wwwroot,dst=/usr/share/nginx/html nginx
# docker run -d --name=nginx-test -v /app/wwwroot:/usr/share/nginx/html nginx
举例:
[root@docker01 ~]# docker run -d --name web -p 80:80 -v /opt/rootwww/:/usr/share/nginx/html nginx
解释:后台创建一个名字为web的nginx ,访问端口为80:80,将/opt/rootwww/挂载到/usr/share/nginx/html。
1b3d90c83c10e506cbb57b20237eacd845a98822ae71c0bbeadb67ba3fbb42fd
[root@docker01 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1b3d90c83c10 nginx "/docker-entrypoint.…" 11 seconds ago Up 11 seconds 0.0.0.0:80->80/tcp web
root@1b3d90c83c10:/# cd /usr/share/nginx/html/
root@1b3d90c83c10:/usr/share/nginx/html# ls
浏览器访问没有
解释:因为挂在的目录没有html文件
解决:在互相挂在的两个目录中选择一个,追加html文件
[root@1b3d90c83c10:/usr/share/nginx/html# echo "wangwenbin DSB" > index.html
在挂载目录下验证,有此文件,持久化完成
[root@docker01 ~]# cd /opt/rootwww/
[root@docker01 /opt/rootwww]# ls
index.html
制作镜像:
1.启动容器之后的应用程序,服务产生的数据尽量放到一个目录下 /data
2.构建不是将已经生成的应用程序数据打包进去
例如:jenkins、gitlab使用docker都是采用-v将他们自身产生的数据持久化宿主机。
九.容器网络
• veth pair:成对出现的一种虚拟网络设备,数据从一端进,从另 一端出。 用于解决网络命名空间之间隔离。
• docker0:网桥是一个二层网络设备,通过网桥可以将Linux支持 的不同的端口连接起来,并实现类似交换机那样的多对多的通信。
Docker使用iptables实现网络通信。
外部访问容器: # iptables -t nat -vnL DOCKE
DNAT:目标地址转换
容器访问外部: # iptables -t nat -vnL POSTROUTING
SNAT源地址转换
十.Dockerfile构建镜像
Docker通过Dockerfile自动构建镜像,Dockerfile 是一个包含用于组建镜像的文本文件,由一条一条的指令组成。
1.Dockerfile常用指令
指令 | 描述 |
---|---|
FROM | 构建新镜像是基于哪个镜像 |
LABEL | 标签 |
RUN | 构建镜像时运行的Shell命令 |
COPY | 拷贝文件或目录到镜像中 |
ADD | 解压压缩包并拷贝 |
ENV | 设置环境变量 |
USER | 为RUN、CMD和ENTRYPOINT执行命令指定运行用户 |
EXPOSE | 声明容器运行的服务端口 |
WORKDIR | 为RUN、CMD、ENTRYPOINT、COPY和ADD设置工作目录 |
CMD | 运行容器时默认执行,如果有多个CMD指令,最后一个生效 |
具体操作:
[root@docker01 ~]# mkdir dockerfile
[root@docker01 /opt]# cd /root/dockerfile/
[root@docker01 ~/dockerfile]# ls
Dockerfile
[root@docker01 ~/dockerfile]# cat Dockerfile
FROM centos:latest
LABEL nginx chuanjian
RUN yum install epel-release -y && \
yum install nginx -y
CMD ["nginx","-g","daemon off;"]
[root@docker01 ~/dockerfile]# docker build -t nginx:V1 .
[root@docker01 ~/dockerfile]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx V1 1c709626ccf5 14 minutes ago 313MB
[root@docker01 ~/dockerfile]# docker run -d --name web3 -p 93:80 -v /opt/rootwww/:/usr/share/nginx/html nginx:V1
41362b7ee57812223e05c55165cc2fc8eb5bc99680823b94d3711228d9ed3419
[root@docker01 ~/dockerfile]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
41362b7ee578 nginx:V1 "nginx -g 'daemon of…" 12 seconds ago Up 12 seconds 0.0.0.0:93->80/tcp web3
验证:
1.构建镜像命令
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](http://www.example.com/Dockerfile)
构建Nginx镜像
FROM centos:7
LABEL maintainer www.ctnrs.com
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/*
ADD nginx-1.15.5.tar.gz /
RUN cd nginx-1.15.5 && \
./configure --prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_stub_status_module && \
make -j 4 && make install && \
mkdir /usr/local/nginx/conf/vhost && \
cd / && rm -rf nginx* && \
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;"]
构建Tomcat镜像
FROM centos:7
MAINTAINER www.ctnrs.com
ENV VERSION=8.5.43
RUN yum install java-1.8.0-openjdk wget curl unzip iproute net-tools -y && \
yum clean all && \
rm -rf /var/cache/yum/*
ADD apache-tomcat-${VERSION}.tar.gz /usr/local/
RUN mv /usr/local/apache-tomcat-${VERSION} /usr/local/tomcat && \
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"]