K8S:CRI(Container Runtime Interface)
Client: 客户端;操作docker服务器的客户端(命令行或者界面)
Docker_Host:Docker主机;安装Docker服务的主机
Docker_Daemon:后台进程;运行在Docker服务器的后台进程
Containers:容器;在Docker服务器中的容器(一个容器一般是一个应用实例,容器间互相隔离)
Images:镜像、映像、程序包;Image是只读模板,其中包含创建Docker容器的说明。容器是由Image运
行而来,Image固定不变。
Registries:仓库;存储Docker Image的地方。官方远程仓库地址: https://hub.docker.com/search
Docker用Go编程语言编写,并利用Linux内核的多种功能来交付其功能。 Docker使用一种称为名称
空间的技术来提供容器的隔离工作区。 运行容器时,Docker会为该容器创建一组名称空间。 这些
名称空间提供了一层隔离。 容器的每个方面都在单独的名称空间中运行,并且对其的访问仅限于
该名称空间。
Docker | 面向对象 |
---|---|
镜像(Image) | 类 |
容器(Container) | 对象(实例) |
容器与虚拟机
namespace | 系统调用参数 | 隔离内容 |
---|---|---|
UTS | CLONE_NEWUTS | 主机和域名 |
IPC | CLONE_NEWIPC | 信号量、消息队列和共享内存 |
PID | CLONE_NEWPID | 进程编号 |
Network | CLONE_NEWNET | 网络设备、网络栈、端口等 |
Mount | CLONE_NEWNS | 挂载点(文件系统) |
User | CLONE_NEWUSER | 用户和用户组 |
cgroup提供的主要功能如下:
cgroup资源控制系统,每种子系统独立地控制一种资源。功能如下
子系统 | 功能 |
---|---|
cpu | 使用调度程序控制任务对CPU的使用 |
cpuacct(CPU Accounting) | 自动生成cgroup中任务对CPU资源使用情况的报告 |
cpuset | 为cgroup中的任务分配独立的CPU(多处理器系统时)和内存 |
devices | 开启或关闭cgroup中任务对设备的访问 |
freezer | 挂起或恢复cgroup中的任务 |
memory | 设定cgroup中任务对内存使用量的限定,并生成这些任务对内存资源使用情况的报告 |
perf_event(Linux CPU性能探测器) | 使cgroup中的任务可以进行统一的性能测试 |
net_cls(Docker未使用) | 通过等级识别符标记网络数据包,从而允许Linux流量监控程序(Tra?icController)识别从具体cgroup中生成的数据包 |
Docker 技术使用 Linux 内核和内核功能(例如 Cgroups 和 namespaces)来分隔进程,以便各进程相互独立运行。这种独立性正是采用容器的目的所在;它可以独立运行多种进程、多个应用程序,更加充分地发挥基础设施的作用,同时保持各个独立系统的安全性。
容器工具(包括 Docker)可提供基于镜像的部署模式。这使得它能够轻松跨多种环境,与其依赖程序共享应用或服务组。Docker 还可在这一容器环境中自动部署应用程序(或者合并多种流程,以构建单个应用程序)。
以下以centos为例;
更多其他安装方式,详细参照文档: https://docs.docker.com/engine/install/centos/
sudo yum remove docker*
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# sudo yum install docker-ce docker-ce-cli containerd.io
#找到所有可用docker版本列表
yum list docker-ce --showduplicates | sort -r
# 安装指定版本,用上面的版本号替换
#sudo yum install docker-ce-.x86_64 docker-ce-cli-.x86_64 containerd.io
#例如
yum install -y docker-ce-19.03.9 docker-ce-cli-19.03.9 containerd.io
https://download.docker.com/linux/centos/7/x86_64/stable/Packages/
rpm -ivh xxx.rpm
可以下载 tar
解压启动即可
https://docs.docker.com/engine/install/binaries/#install-daemon-and-client-binaries-on-linux
# 启动
systemctl start docker
# 开机自启
systemctl enable docker
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://c9jwzg2k.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
# 阿里云的镜像是从docker hub来的,我们配置了加速,默认是从阿里云(缓存)下载
# 以后docker下载直接从阿里云拉取相关镜像
#/etc/docker/daemon.json 是Docker的核心配置文件。
{
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com"
]
}
https://documentation.portainer.io/
Portainer社区版2.0拥有超过50万的普通用户,是功能强大的开源工具集,可让您轻松地在Docker,Swarm,Kubernetes和Azure ACI中构建和管理容器。 Portainer的工作原理是在易于使用的GUI后面隐藏使管理容器变得困难的复杂性。通过消除用户使用CLI,编写YAML或理解清单的需求,Portainer使部署应用程序和解决问题变得如此简单,任何人都可以做到。 Portainer开发团队在这里为您的Docker之旅提供帮助;
# 服务端部署
docker run -d -p 8000:8000 -p 9000:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data --name prtainer portainer/portainer
docker run -d \
-p 9000:9000 \ # portainer默认端口是9000,映射到本地9000端口,通过本地地址访问
--restart=always \ # 设置自动重启
-v /var/run/docker.sock:/var/run/docker.sock \ # 单机必须指定docker.sock
--name Prtainer portainer/portainer
# 访问 9000 端口即可
#agent端部署
docker run -d -p 9001:9001 --name portainer_agent --restart=always -v
/var/run/docker.sock:/var/run/docker.sock -v
/var/lib/docker/volumes:/var/lib/docker/volumes portainer/agent
# 修改容器总是开机重启
docker update 容器id --restart=always
所有Docker命令手册:https://docs.docker.com/engine/reference/commandline/docker/
命令 | 作用 |
---|---|
attach | 绑定到运行中容器的 标准输入, 输出,以及错误流(这样似乎也能进入容器内容,但是一定小心,他们操作的就是控制台,控制台的退出命令会生效,比如redis,nginx…) |
build | 从一个 Dockerfile 文件构建镜像 |
commit | 把容器的改变 提交创建一个新的镜像 |
cp | 容器和本地文件系统间 复制 文件/文件夹 |
create | 创建新容器,但并不启动(注意与docker run 的区分)需要手动启动。start\stop |
diff | 检查容器里文件系统结构的更改【A:添加文件或目录 D:文件或者目录删除 C:文件或者目录更改】 |
events | 获取服务器的实时事件 |
exec | 在运行时的容器内运行命令 |
export | 导出容器的文件系统为一个tar文件。commit是直接提交成镜像,export是导出成文件方便传输 |
history | 显示镜像的历史 |
images | 列出所有镜像 |
import | 导入tar的内容创建一个镜像,再导入进来的镜像直接启动不了容器。/docker-entrypoint.sh nginx -g ‘daemon o?;’ docker ps --no-trunc 看下之前的完整启动命令再用他 |
info | 显示系统信息 |
inspect | 获取docker对象的底层信息 |
kill | 杀死一个或者多个容器 |
load | 从 tar 文件加载镜像 |
login | 登录Docker registry |
logout | 退出Docker registry |
logs | 获取容器日志;容器以前在前台控制台能输出的所有内容,都可以看到 |
pause | 暂停一个或者多个容器 |
port | 列出容器的端口映射 |
ps | 列出所有容器 |
pull | 从registry下载一个image 或者repository |
push | 给registry推送一个image或者repository |
rename | 重命名一个容器 |
restart | 重启一个或者多个容器 |
rm | 移除一个或者多个容器 |
rmi | 移除一个或者多个镜像 |
run | 创建并启动容器 |
save | 把一个或者多个镜像保存为tar文件 |
search | 去docker hub寻找镜像 |
start | 启动一个或者多个容器 |
stats | 显示容器资源的实时使用状态 |
stop | 停止一个或者多个容器 |
tag | 给源镜像创建一个新的标签,变成新的镜像 |
top | 显示正在运行容器的进程 |
unpause | pause的反操作 |
update | 更新一个或者多个docker容器配置 |
version | Show the Docker version information |
container | 管理容器 |
image | 管理镜像 |
network | 管理网络 |
volume | 管理卷 |
根据正在运行的容器制作出相关的镜像:反向
根据镜像启动一个容器:正向
有了Docker:
1、先去软件市场搜镜像:https://registry.hub.docker.com/ docker hub
2、下载镜像 docker pull xxx
3、启动软件 docker run 镜像名;
对于镜像的所有管理操作都在这一个命令:docker image --help
# 查看容器
docker ps
# 查看停止的容器
docker ps -f status=exited
# 查看所有容器(包括运行和停止)。
docker ps -a
# 查看最后一次运行的容器。
docker ps -l
# 列出最近创建的 n 个容器。
docker ps -n 5
# 列出所有镜像
docker images
# 以redis为例
docker pull redis
# 不写标签相当于
docker pull redis:latest(最新版)
# 创建容器
docker create --name myredis -p 6379:6379 redis
docker create --name myredis -p 6379(主机的端口):6379(容器的端口) redis
https://docs.docker.com/engine/reference/commandline/create/
# 用create创建的容器要用start启动
docker start 容器名或者容器id
docker start myredis
# 停止容器
docker stop 容器名或者容器id
docker stop myredis
# 重启容器
docker restart 容器名或者容器id
docker restart myredis
# 删除容器
docker rm 容器名或者容器id
# 强制删除
docker rm -f 容器名或者容器id
# 删除全部容器
docker rmi -f $(docker ps -aq)
# 删除镜像
docker rmi 镜像名或者镜像id
# 强制删除
docker rmi -f 镜像名或者镜像id
# 删除全部镜像
docker rmi -f $(docker images -aq)
# 强制停止容器
docker kill 容器名或者容器id
# 查看容器端口映射
docker port 容器名或者容器id
docker port myredis
# 查看容器运行日志
docker logs 容器名或者容器id
docker logs myredis
# 实时查看
docker logs -f myredis
# 查看最后100 行日志
docker logs -f -t --tail 100 myredis
# 查看最近30分钟的日志
docker logs --since 30m myredis
# 查看时间段日志
docker logs -t --since="2021-11-01" --until "2021-11-05" myredis
# 重命名容器
docker rename 容器名 新容器名
docker rename myredis redis
# 查看容器资源的实时使用状态
docker stats 容器名或者容器id
# 更新容器配置
# 更新容器为开机自启
docker update 容器名或者容器id --restart=always
# 给镜像重新打标签
docker tag 原镜像:标签 新镜像名:标签
# 移除游离镜像 dangling:游离镜像(没有镜像名字的)
docker image prune
# 清理docker system
docker system prune
# 暂停容器
docker pause 容器名或者容器id
# 启动已暂停的容器
docker unpause 容器名或者容器id
# 查看镜像详细信息
docker inspect 镜像id或者镜像名
# 查看容器详细信息
docker container inspect 容器名或者容器id
# network volume等等都可以查看
docker inspect image/network/volume ....
# 进入容器
docker exec -it 容器名或者容器id /bin/bash
# 0用户,以特权方式进入容器
docker exec -it -u 0:0 --privileged myredis /bin/bash
https://docs.docker.com/engine/reference/commandline/exec/
# 进容器 绑定的是控制台. 可能导致容器停止。不要用这个
docker attach
# 导出镜像
docker export 导出的文件被import导入以后变成镜像,并不能直接启动容器,需要知道之前的启动命令
docker export -o nginx.tar 容器id
docker import nginx.tar mynginx:v6
(docker ps --no-trunc),然后再用下面启动。
docker run -d -P mynginx:v6 /docker-entrypoint.sh nginx -g 'daemon off;'
或者docker image inspect 看之前的镜像,把 之前镜像的 Entrypoint的所有和 Cmd的连接起来就
能得到启动命令
docker save -o busybox.tar busybox:latest 把busybox镜像保存成tar文件
docker load -i busybox.tar 把压缩包里面的内容直接导成镜像
# 一般运行中的容器会常年修改,我们要使用最终的新镜像,把新的镜像放到远程docker hub,方便后来在其他机器下载
docker commit -a xueqimiao -m "first commit" mynginx4 mynginx:v4
# 会产生游离镜像
-d: 后台运行容器,并返回容器ID
;-i: 以交互模式运行容器,通常与 -t 同时使用
;-P: 随机端口映射,容器内部端口随机映射到主机的端口
-p:指定端口映射,格式为:主机(宿主)端口:容器端口
-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用
--name="nginx-lb":为容器指定一个名称
;-e username="ritchie": 设置环境变量
;--cpuset="0-2" or --cpuset="0,1,2": 绑定容器到指定CPU运行
;-m :设置容器使用内存最大值
;--net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型
;--restart , 指定重启策略,可以写--restart=awlays 总是故障重启
--volume , -v: 绑定一个卷。一般格式 主机文件或文件夹:虚拟机文件或文件夹
# 注意 外部的/nginx/conf下面的内容必须存在,否则挂载会覆盖
docker run --name nginx-app \
-v /app/nginx/html:/usr/share/nginx/html:ro \
-v /app/nginx/conf:/etc/nginx
-d nginx:1.20.1
# nginx目录放在/opt/docker/下
# 随便启动一个 nginx 实例,只是为了复制出配置
docker run -p 80:80 -p 443:443 --name nginx443 -d nginx:1.20.1
mkdir -p /usr/local/docker/nginx/html
mkdir -p /usr/local/docker/nginx/logs
mkdir -p /usr/local/docker/nginx/conf
# 复制到/opt/docker/temp下
docker container cp nginx:/etc/nginx /opt/docker/temp
# 比如
docker container cp 8662e037621d:/etc/nginx /usr/local/docker/nginx/conf/
mv /usr/local/docker/nginx/conf/nginx/* /usr/local/docker/nginx/conf
rm -rf /opt/docker/temp
docker stop nginx
docker rm $Containerid
docker run -p 80:80 --name nginx \
-v /opt/docker/nginx/html:/usr/share/nginx/html \
-v /opt/docker/nginx/logs:/var/log/nginx \
-v /opt/docker/nginx/conf/:/etc/nginx \
-d nginx:1.10
docker run -p 80:80 -p 443:443 --name nginx443 \
-v /usr/local/docker/nginx/html:/usr/share/nginx/html \
-v /usr/local/docker/nginx/logs:/var/log/nginx \
-v /usr/local/docker/nginx/conf/:/etc/nginx \
-d nginx:1.20.1
# 5.7版本
docker run -p 3306:3306 --name mysql57-app \
-v /app/mysql/log:/var/log/mysql \
-v /app/mysql/data:/var/lib/mysql \
-v /app/mysql/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql:5.7
#8.x版本,引入了 secure-file-priv 机制,磁盘挂载将没有权限读写data数据,所以需要将权限透传,
或者chmod -R 777 /app/mysql/data
# --privileged 特权容器,容器内使用真正的root用户
docker run -p 3306:3306 --name mysql8-app \
-v /app/mysql/conf:/etc/mysql/conf.d \
-v /app/mysql/log:/var/log/mysql \
-v /app/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
--privileged \
-d mysql
docker run -d --name mysql \-p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 \-v /usr/local/docker/mysql/mysql:/etc/mysql \-v /usr/local/docker/mysql/logs:/var/log/mysql \-v /usr/local/docker/mysql/data/:/var/lib/mysql \mysql:5.7 --lower_case_table_names=1
# 提前准备好redis.conf文件,创建好相应的文件夹。如:
port 6379
appendonly yes
#更多配置参照 https://raw.githubusercontent.com/redis/redis/6.0/redis.conf
docker run -p 6379:6379 --name redis \
-v /app/redis/redis.conf:/etc/redis/redis.conf \
-v /app/redis/data:/data \
-d redis:6.0.8 \
redis-server /etc/redis/redis.conf --appendonly yes
#准备文件和文件夹,并chmod -R 777 xxx
#配置文件内容,参照
https://www.elastic.co/guide/en/elasticsearch/reference/7.5/node.name.html 搜索相
关配置
# 考虑为什么挂载使用esconfig ...
docker run --name=elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms300m -Xmx300m" \
-v /app/es/data:/usr/share/elasticsearch/data \
-v /app/es/plugins:/usr/shrae/elasticsearch/plugins \
-v esconfig:/usr/share/elasticsearch/config \
-d elasticsearch:7.12.0
#######################################
docker pull elasticsearch:7.4.2 存储和检索数据
docker pull kibana:7.4.2 可视化检索数据
mkdir -p /opt/docker/elasticsearch/config # 用来存放配置文件
mkdir -p /opt/docker/elasticsearch/data # 数据
echo "http.host: 0.0.0.0" >/opt/docker/elasticsearch/config/elasticsearch.yml # 允许任何机器访问
chmod -R 777 /opt/docker/elasticsearch/ ## 设置elasticsearch文件可读写权限
# 启动es
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx512m" \
-v /opt/docker/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /opt/docker/elasticsearch/data:/usr/share/elasticsearch/data \
-v /opt/docker/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.4.2
#以后再外面装好插件重启就可
#特别注意:
-e ES_JAVA_OPTS="-Xms64m -Xmx128m" \ 测试环境下,设置 ES 的初始内存和最大内存,否则导致过大启动不了ES
# 开机启动
docker update elasticsearch --restart=always
# 启动kibana
docker run --name kibana -e ELASTICSEARCH_HOSTS=http://42.192.52.168:9200 -p 5601:5601 -d kibana:7.4.2
http://42.192.52.168:9200 改成自己Elasticsearch上的地址
# 考虑,如果我们每次 -v 都是指定磁盘路径,是不是很麻烦?
docker run --name tomcat-app -p 8080:8080 \
-v tomcatconf:/usr/local/tomcat/conf \
-v tomcatwebapp:/usr/local/tomcat/webapps \
-d tomcat:jdk8-openjdk-slim-buster
docker run -d \
--name dubbo_admin \
-p 8083:8080 \
-e dubbo.registry.address=zookeeper://172.16.253.50:2181 \
-e dubbo.admin.root.password=root \
-e dubbo.admin.guest.password=root \
chenchuxin/dubbo-admin
docker run --name='activemq' \
-itd \
-p 8161:8161 \
-p 61616:61616 \
-e ACTIVEMQ_ADMIN_LOGIN=admin \
-e ACTIVEMQ_ADMIN_PASSWORD=admin \
--restart=always \
-v activemq_data:/data/activemq \
-v activemq_log:/var/log/activemq \
-v activemq_conf:/opt/activemq/conf \
webcenter/activemq:latest
# 启动 MongoDB
docker run -d --name mongo-yapi mongo
# 获取yapi镜像
docker pull registry.cn-hangzhou.aliyuncs.com/anoy/yapi
# 初始化数据库索引及管理员账号
docker run -it --rm \
--link mongo-yapi:mongo \
--entrypoint npm \
--workdir /api/vendors \
registry.cn-hangzhou.aliyuncs.com/anoy/yapi \
run install-server
# 启动yapi服务
docker run -d \
--name yapi \
--link mongo-yapi:mongo \
--workdir /api/vendors \
-p 3000:3000 \
registry.cn-hangzhou.aliyuncs.com/anoy/yapi \
server/app.js
no,默认策略,在容器退出时不重启容器
on-failure,在容器非正常退出时(退出状态非0),才会重启容器
on-failure:3,在容器非正常退出时重启容器,最多重启3次
always,在容器退出时总是重启容器
unless-stopped,在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容
器
docker search rabbitmq
docker run -d --hostname my-rabbit --name rabbit -p 15672:15672 -p 5672:5672 rabbitmq
docker exec -it 镜像ID /bin/bash
# 开启Web-UI后台界面
rabbitmq-plugins enable rabbitmq_management
http://linuxip地址:15672,用户名和密码默认都是guest
# stats in management UI are disabled on this node
docker exec -it {rabbitmq容器名称或者id} /bin/bash
cd /etc/rabbitmq/conf.d/
echo management_agent.disable_metrics_collector = false > management_agent.disable_metrics_collector.conf
# 重启容器
# 进入容器
docker exec -it 容器名或者容器id /bin/bash
# 0用户,以特权方式进入容器
docker exec -it -u 0:0 --privileged myredis /bin/bash
docker build -t imageName -f DockerfileName .
# 不带缓存构建
docker build --no-cache
Created
(新建)、Up
(运行中)、Pause
(暂停)、Exited
(退出)
问题:
容器: 某个软件完整的运行环境;包含了一个小型的linux系统
宿主机里面同时4个nginx; 一个nginx运行时完整环境有20MB?
docker装的和宿主机的优缺点:
优点:docker的移植性、便捷性高于在宿主机部署、进程隔离、很方便的资源限制
缺点:docker基于虚拟化技术,损失不到3%的性能。
镜像 容器
镜像
(Image):固定不变的。一个镜像可以启动很多容器
容器
(Container):文件系统可能logs经常变化的,一个镜像可以启动很多容器。
docker在底层使用自己的存储驱动。来组件文件内容 storage drivers。
截取的nginx的分层
docker history nyginx
nginx这个镜像怎么存的
使用:docker image inspect nginx
指示了镜像怎么存的
LowerDir :底层目录; diff(只是存储不同);包含小型linux和装好的软件
/var/lib/docker/overlay2/67b3802c6bdb5bcdbcccbbe7aed20faa7227d584ab37668a03ff6952e
631f7f2/diff:用户文件;
/var/lib/docker/overlay2/f56920fac9c356227079df41c8f4b056118c210bf4c50bd9bb077bdb4
c7524b4/diff: nginx的启动命令放在这里
/var/lib/docker/overlay2/0e569a134838b8c2040339c4fdb1f3868a7118dd7f4907b40468f5fe6
0f055e5/diff: nginx的配置文件在这里
/var/lib/docker/overlay2/2b51c82933078e19d78b74c248dec38164b90d80c1b42f0fdb1424953
207166e/diff: 小linux系统
倒着看
小linux系统(FROM apline) + Dockerfile的每一个命令可能都引起了系统的修改,所以和git一样,只记录变化
ls -i
"LowerDir":
"/var/lib/docker/overlay2/41e4fa41a2ad1dca9616d4c8254a04c4d9d6a3d462
c862f1e9a0562de2384dbc-
init/diff:/var/lib/docker/overlay2/e3b8bdbb0cfbe5450696c470994b3f99e
8a7942078e2639a788027529c6278f7/diff:/var/lib/docker/overlay2/67b380
2c6bdb5bcdbcccbbe7aed20faa7227d584ab37668a03ff6952e631f7f2/diff:/var
/lib/docker/overlay2/f56920fac9c356227079df41c8f4b056118c210bf4c50bd
9bb077bdb4c7524b4/diff:/var/lib/docker/overlay2/0e569a134838b8c20403
39c4fdb1f3868a7118dd7f4907b40468f5fe60f055e5/diff:/var/lib/docker/ov
erlay2/2b51c82933078e19d78b74c248dec38164b90d80c1b42f0fdb14249532071
66e/diff",
"MergedDir":
"/var/lib/docker/overlay2/41e4fa41a2ad1dca9616d4c8254a04c4d9d6a3d462
c862f1e9a0562de2384dbc/merged",
"UpperDir": (镜像的上层可以感知变
化)"/var/lib/docker/overlay2/41e4fa41a2ad1dca9616d4c8254a04c4d9d6a3d
462c862f1e9a0562de2384dbc/diff",【容器的修改后的文件,保存再宿主机哪里呀。
容器删除后,那些容器目录还存在吗?一定不再】
"WorkDir":
"/var/lib/docker/overlay2/41e4fa41a2ad1dca9616d4c8254a04c4d9d6a3d462
c862f1e9a0562de2384dbc/work"
LowerDir(底层)\UpperDir()\MergedDir\WorkDir(临时东西)
docker底层的 storage driver完成了以上的目录组织结果;
哪些东西适合容器运行?
docker启动一个MySQL,默认什么都不做?
MySQL就会丢失数据
Docker映像由一系列层组成。 每层代表图像的Dockerfile中的一条指令。 除最后一层外的每一层都是只读的。 如以下Dockerfile:
FROM ubuntu:15.04
COPY . /app
RUN make /app
CMD python /app/app.py
# 每一个指令都可能会引起镜像改变,这些改变类似git的方式逐层叠加。
该Dockerfile包含四个命令,每个命令创建一个层。
FROM语句从ubuntu:15.04映像创建一个图层开始。
COPY命令从Docker客户端的当前目录添加一些文件。
RUN命令使用make命令构建您的应用程序。
最后,最后一层指定要在容器中运行的命令。
每一层只是与上一层不同的一组。 这些层彼此堆叠。
创建新容器时,可以在基础层之上添加一个新的可写层。 该层通常称为“容器层”。 对运行中
的容器所做的所有更改(例如写入新文件,修改现有文件和删除文件)都将写入此薄可写容
器层。
容器和镜像之间的主要区别是可写顶层。
在容器中添加新数据或修改现有数据的所有写操作都存储在此可写层中。
删除容器后,可写层也会被删除。 基础图像保持不变。 因为每个容器都有其自己的可写容
器层,并且所有更改都存储在该容器层中,所以多个容器可以共享对同一基础映像的访问,
但具有自己的数据状态。
docker ps -s
size:用于每个容器的可写层的数据量(在磁盘上)。
virtual size:容器使用的用于只读图像数据的数据量加上容器的可写图层大小。
多个容器可以共享部分或全部只读图像数据。
从同一图像开始的两个容器共享100%的只读数据,而具有不同图像的两个容器(具有相同的层)共享这些公共
层。 因此,不能只对虚拟大小进行总计。这高估了总磁盘使用量,可能是一笔不小的数目。
busybox:是一个集成了一百多个最常用Linux命令和工具的软件。linux工具里的瑞士军刀
alpine:Alpine操作系统是一个面向安全的轻型Linux发行版经典最小镜像,基于busybox,功能比
Busybox完善。
slim:docker hub中有些镜像有slim标识,都是瘦身了的镜像。也要优先选择
无论是制作镜像还是下载镜像,优先选择alpine类型.
每一个容器里面的内容,支持三种挂载方式:
1)、docker自动在外部创建文件夹自动挂载容器内部指定的文件夹内容【Dockerfile VOLUME指令的作用】
2)、自己在外部创建文件夹,手动挂载
3)、可以把数据挂载到内存中。
–mount 挂载到 linux宿主机,手动挂载(不用了)
-v 可以自动挂载,到linux主机或者docker自动管理的这一部分区域
docker run -dP -v :/etc/nginx nginx
#docker将创建出匿名卷,并保存容器/etc/nginx下面的内容
# -v 宿主机:容器里的目录
docker run -dP -v nginx:/etc/nginx nginx
#docker将创建出名为nginx的卷,并保存容器/etc/nginx下面的内容
如果将空卷装入存在文件或目录的容器中的目录中,则容器中的内容(复制)到该卷中。
如果启动一个容器并指定一个尚不存在的卷,则会创建一个空卷。
-v 宿主机绝对路径:Docker容器内部绝对路径:叫挂载;这个有空挂载问题
-v 不以/开头的路径:Docker容器内部绝对路径:叫绑定(docker会自动管理,docker不会把他当成目录,而把它当前卷)
以上用哪个比较好??????
nginx--Docker
/usr/share/nginx/html
nginx测试html挂载几种不同情况:
不挂载 效果:访问默认欢迎页
-v /root/html:/usr/share/nginx/html 效果:访问forbidden
-v html:/usr/share/nginx/html:ro 效果:访问默认欢迎页(:ro 表示只读)
-v /usr/share/nginx/html 效果:匿名卷 (什么都不写也不要加冒号,直接写容器内的目录)
原因:
-v html:/usr/share/nginx/html; docker inspect 容器的时候; docker自动管理的方式
# -v不以绝对路径方式;
### 1、先在docker底层创建一个你指定名字的卷(具名卷) html
### 2、把这个卷和容器内部目录绑定
### 3、容器启动以后,目录里面的内容就在卷里面存着;
#####-v nginxhtml:/usr/share/nginx/html 也可以以下操作
## 1、 docker create volume nginxhtml 如果给卷里面就行修改,容器内部的也就改
了。
## 2、 docker volume inspect nginxhtml
## 3、docker run -d -P -v nginxhtml:/usr/share/nginx/html --
name=nginx777 nginx
# 可以看到
"Mounts": [
{
"Type": "volume", //这是个卷
"Name": "html", //名字是html
"Source": "/var/lib/docker/volumes/html/_data", //宿主
机的目录。容器里面的哪两个文件都在
"Destination": "/usr/share/nginx/html", //容器内部
"Driver": "local",
"Mode": "z",
"RW": true, //读写模式
"Propagation": ""
}
]
#卷:就是为了保存数据
docker volume #可以对docker自己管理的卷目录进行操作;
/var/lib/docker/volumes(卷的根目录)
如果将绑定安装或非空卷安装到存在某些文件或目录的容器中的目录中,则这些文件或目录会被
安装遮盖,就像您将文件保存到Linux主机上的/ mnt中一样,然后 将USB驱动器安装到/ mnt中。
在卸载USB驱动器之前,/ mnt的内容将被USB驱动器的内容遮盖。 被遮盖的文件不会被删除或更
改,但是在安装绑定安装或卷时将无法访问。
总结:外部目录覆盖内部容器目录内容,但不是修改。所以谨慎,外部空文件夹挂载方式也会导
致容器内部是空文件夹
docker run -dP -v /my/nginx:/etc/nginx nginx
# bind mount和 volumes 的方式写法区别在于
# 所有以/开始的都认为是 bind mount ,不以/开始的都认为是 volumes.
警惕bind mount 方式,文件挂载没有在外部准备好内容而导致的容器启动失败问题
# 一行命令启动nginx,并且配置文件和html页面。需要知道卷的位置才能改
docker run -d -P -v nginxconf:/etc/nginx/ -v nginxpage:/usr/share/nginx/html nginx
# 想要实现 docker run -d -P -v /root/nginxconf:/etc/nginx/ -v /root/nginxhtml:/usr/share/nginx/html --name=nginx999 nginx
### 1、提前准备好东西 目录nginxconf,目录里面的配置we年都放里面,,再调用命令
### 2、docker cp nginxdemo:/etc/nginx /root/nginxconf #注意/的使用
### 3、docker run -d -P -v /root/nginxconf:/etc/nginx/ -v /root/nginxhtml:/usr/share/nginx/html --name=nginx999 nginx
docker volume create xxx:创建卷名
docker volume inspect xxx:查询卷详情
docker volume ls: 列出所有卷
docker volume prune: 移除无用卷
cp的细节
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|- :把容器里面的复制出来
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH:把外部的复制进去
SRC_PATH 指定为一个文件
SRC_PATH 指定为一个目录
自动创建文件夹不会做递归。把父文件夹做好
docker cp index.html mynginx4:/usr/share/nginx/html
docker cp mynginx4:/etc/nginx/nginx.conf nginx.conf
docker create -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 --name hello-mysql
mysql:5.7
–link name:alias ,name连接容器的名称,alias连接的别名
场景:我们无需暴露mysql的情况下,让web应用使用mysql;
docker run -d -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
docker run -d --link mysql01:mysql --name tomcat tomcat:7
docker exec -it tomcat bash
cat /etc/hosts
ping mysql
Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。
Linux虚拟网络技术。
Docker容器网络就很好的利用了Linux虚拟网络技术,在本地主机和容器内分别创建一个虚拟接口,并让
他们彼此联通(这样一对接口叫veth pair);
Docker中的网络接口默认都是虚拟的接口。虚拟接口的优势就是转发效率极高(因为Linux是在内核中进
行数据的复制来实现虚拟接口之间的数据转发,无需通过外部的网络设备交换),对于本地系统和容器
系统来说,虚拟接口跟一个正常的以太网卡相比并没有区别,只是他的速度快很多。
原理:
1、每一个安装了Docker的linux主机都有一个docker0的虚拟网卡。桥接网卡
2、每启动一个容器linux主机多了一个虚拟网卡。
3、docker run -d -P --name tomcat --net bridge tomcat:8
网络模式 | 配置 | 说明 |
---|---|---|
bridge模式 | –net=bridge | 默认值,在Docker网桥docker0上为容器创建新的网络栈 |
none模式 | –net=none | 不配置网络,用户可以稍后进入容器,自行配置 |
container模式 | –net=container:name/id | 容器和另外一个容器共享Network namespace。kubernetes中的pod就是多个容器共享一个Network namespace。 |
host模式 | –net=host | 容器和宿主机共享Network namespace |
用户自定义 | –net=自定义网络 | 用户自己使用network相关命令定义网络,创建容器的时候可以指定为自己定义的网络 |
#1、docker0网络的特点。,
默认、域名访问不通、--link 域名通了,但是删了又不行
#2、可以让容器创建的时候使用自定义网络
1、自定义创建的默认default "bridge"
2、自定义创建一个网络网络
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
docker run -d -P --name=tomcat1 --network=mynet tomcat:jre8-alpine
docker run -d -P --name=redisserver --network=mynet redis
# 以上tomcat和redis可以互相ping通
# 对于没有ping命令的容器可以这样测试
docker run -it --network container:redisserver alpine
# 所有东西实时维护好,直接域名ping通
docker network connect [OPTIONS] NETWORK CONTAINER
#3、跨网络连接别人就用。把tomcat加入到mynet网络
docker network connect mynet tomcat
效果:
1、自定义网络,默认都可以用主机名访问通
2、跨网络连接别人就用 docker network connect mynet tomcat
#4、命令
1、容器启动,指定容器ip。 docker run --ip 192.168.0.3 --net 自定义网络
2、创建子网。docker network create --subnet 指定子网范围 --driver bridge 所有东西实时
维护好,直接域名ping同
3、docker compose 中的网络默认就是自定义网络方式