docker基础
一、基本概念
1、Docker架构
Docker 架构包括以下几个核心组件:
1. Docker 客户端 (Client): 用户与 Docker 交互的命令行工具或 API。
2. Docker 服务器 (Server): 负责管理镜像、容器、网络等资源的后台服务。
3. Docker 镜像 (Image): 是一个只读的模板,包含用于创建容器的文件系统和应用程序代码。
4. Docker 容器 (Container): 是 Docker 的基本执行单元,一个镜像可以创建多个容器,容器之间互相隔离,包括文件系统、网络、进程等资源。
5. Docker Registry (仓库): 存储 Docker 镜像的中央仓库,提供镜像的下载和上传服务。
6. Docker Compose: 是一个用于定义和运行多个容器的工具,简化了容器编排的复杂度。
7. Docker Swarm: 是 Docker 的集群管理工具,可以将多个 Docker 主机组成一个虚拟的 Docker 主机集群,提供负载均衡、容错等功能。
这些组件协同工作,构成了 Docker 强大的应用容器化解决方案。
2、Docker隔离原理
Docker 通过多种技术实现容器的隔离,包括:
1. 命名空间 (Namespace):Docker 使用多种命名空间,如 mount、pid、net、ipc、uts 等,将容器的进程、网络、文件系统等资源与主机分离,使得容器拥有自己独立的运行环境。
2. 控制组 (Cgroups):Docker 使用 Cgroups 控制组技术,限制容器内部进程使用的资源,如 CPU、内存、磁盘等。
3. 文件系统:Docker 使用 OverlayFS 技术,将容器的文件系统与主机分离,每个容器都有自己独立的文件系统,并可以使用 Docker 镜像中的文件系统层,实现镜像共享和快速启动。
4. 安全机制:Docker 使用安全机制,如 seccomp、AppArmor、SELinux 等,限制容器内部进程的系统调用和权限,防止容器被攻击和滥用。
5. 网络隔离:Docker 使用网络隔离技术,将容器的网络与主机分离,每个容器都有自己独立的网络命名空间和 IP 地址,实现容器之间的隔离和互通。
通过这些技术的组合,Docker 实现了容器之间的隔离,使得容器可以在相互独立的环境中运行,同时也保障了容器的安全和稳定性。
3、Docker安装
1、移除旧版本
sudo yum remove docker*
1.删除docker及安装时自动安装的所有包
apt-get autoremove docker docker-ce docker-engine docker.io containerd runc
2.查看docker是否卸载干净
dpkg -l | grep docker
dpkg -l |grep ^rc|awk '{print $2}' |sudo xargs dpkg -P # 删除无用的相关的配置文件
3.删除没有删除的相关插件
apt-get autoremove docker-ce-*
4.删除docker的相关配置&目录
rm -rf /etc/systemd/system/docker.service.d
2、设置docker yum源
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
3、安装最新的docker image
sudo yum install docker-ce docker-ce-cli containerd.io
4、安装指定版本的docker image
1、在线安装
#找到所有可用docker版本列表
yum list docker-ce --showduplicates | sort -r
# 安装指定版本,用上面的版本号替换<VERSION_STRING>
sudo yum install docker-ce-<VERSION_STRING>.x86_64 docker-ce-cli-
<VERSION_STRING>.x86_64 containerd.io
#例如:
#yum install docker-ce-3:20.10.5-3.el7.x86_64 docker-ce-cli-3:20.10.5-
3.el7.x86_64 containerd.io
#注意加上 .x86_64 大版本号
2、离线安装
- 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
5、启动服务
systemctl start docker
systemctl enable docker
6、镜像加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"exec-opts": ["native.cgroupdriver=systemd"],
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com",
"https://mfs5bvup.mirror.aliyuncs.com",
"https://dockerproxy.com",
"https://mirror.baidubce.com",
"https://ccr.ccs.tencentyun.com",
"https://docker.m.daocloud.io",
"https://docker.nju.edu.cn",
"https://docker.mirrors.ustc.edu.cn"
],
"insecure-registries": [
"192.168.41.200"
]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
#以后docker下载直接从阿里云拉取相关镜像
7、可视化界面-Portainer
1、什么是Portainer
Portainer社区版2.0拥有超过50万的普通用户,是功能强大的开源工具集,可让您轻松地在Docker,
Swarm,Kubernetes和Azure ACI中构建和管理容器。 Portainer的工作原理是在易于使用的GUI后面隐藏
使管理容器变得困难的复杂性。通过消除用户使用CLI,编写YAML或理解清单的需求,Portainer使部署
应用程序和解决问题变得如此简单,任何人都可以做到。 Portainer开发团队在这里为您的Docker之旅提
供帮助;
2、安装
# 服务端部署
docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v
/var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data
portainer/portainer-ce
# 访问 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命令
1、常用命令
命令 | 作用 |
---|---|
attach | 绑定到运行中容器的 标准输入, 输出,以及错误流(这样似乎也能进入容器内容,但 是一定小心,他们操作的就是控制台,控制台的退出命令会生效,比如 redis,nginx…) |
build | 从一个 Dockerfile 文件构建镜像 |
commit | 把容器的改变 提交创建一个新的镜像 |
cp | 容器和本地文件系统间 复制 文件/文件夹cp -rp[原文件或目录] [目标文件或目录] -r 复制目录 - p 保留文件属性 |
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 |
info | 显示系统信息 |
inspect | 获取docker对象的底层信息 |
kill | 杀死一个或者多个容器 |
load | 从 tar 文件加载镜像 docker load -i xxx.tar |
login | 登录Docker registry |
logout | 退出Docker registry |
logs | 获取容器日志;容器以前在前台控制台能输出的所有内容,都可以看到 |
pause | 暂停一个或者多个容器 |
port | 列出容器的端口映射 |
ps | 列出所有容器 docker ps -a 列出包括已停止的所有容器 |
pull | 从registry下载一个image 或者repository |
push | 给registry推送一个image或者repository |
rename | 重命名一个容器 |
restart | 重启一个或者多个容器 |
rm | 移除一个或者多个容器 |
rmi | 移除一个或者多个镜像 |
run | 创建并启动容器 |
save | 把一个或者多个镜像保存为tar文件 docker save -o [容器名称]:[容器标签] > xxx.tar |
search | 去docker hub寻找镜像 |
start | 启动一个或者多个容器 |
stop | 停止一个或者多个容器 |
tag | 给源镜像创建一个新的标签,变成新的镜像 |
unpause | pause的反操作 |
update | 更新一个或者多个docker容器配置 |
version | Show the Docker version information |
container | 管理容器 |
image | 管理镜像 |
network | 管理网络 |
volume | 管理卷 |
stats | 显示容器资源的实时使用状态 |
top | 显示正在运行容器的进程 |
# 根据正在运行的容器制作出相关的镜像:反向
根据镜像启动一个容器:正向
# docker pull redis == docker pull redis:latest(最新版)
# 镜像是怎么做成的。基础环境+软件
redis的完整镜像应该是: linux系统+redis软件
alpine:超级经典版的linux 5mb;+ redis = 29.0mb
没有alpine3的:就是centos基本版
# 以后自己选择下载镜像的时候尽量使用
alpine: slim:
docker rmi -f $(docker images -aq) #删除全部镜像
docker image prune #移除游离镜像 dangling:游离镜像(没有镜像名字的,注意看结果可能删不掉)
docker tag 原镜像:标签 新镜像名:标签 #重命名
docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
docker create [设置项] 镜像名 [启动] [启动参数...]
docker create redis: 按照redis:latest镜像启动一个容器
docker kill是强制kill -9(直接拔电源);
docker stop可以允许优雅停机(当前正在运行中的程序处理完所有事情后再停止)
docker create --name myredis -p 6379(主机的端口):6379(容器的端口) redis
-p port1:port2
port1是必须唯一的,那个是没关系的。
docker run --name myredis2 -p 6379:6379 -p 8888:6379 redis :默认是前台启动的,一
般加上-d 让他后台悄悄启动, 虚拟机的很多端口绑定容器的一个端口是允许的
docker run -d == docker create + docker start
#启动了nginx;一个容器。docker 容器里面安装了nginx,要对nginx的所有修改都要进容器
#进容器:
docker attach 绑定的是控制台. 可能导致容器停止。不要用这个
docker exec -it -u 0:0 --privileged mynginx4 /bin/bash: 0用户,以特权方式进入容器
docker container inspect 容器名 = docker inspect 容器名
docker inspect image/network/volume ....
# 一般运行中的容器会常年修改,我们要使用最终的新镜像
docker commit -a hzhero -m "first commit" mynginx4 mynginx:v4
#把新的镜像放到远程docker hub,方便后来在其他机器下载
#---------export操作容器/import-------------------
docker export导出的文件被import导入以后变成镜像,并不能直接启动容器,需要知道之前的启动命令
(docker ps --no-trunc),然后再用下面启动。
docker run -d -P mynginx:v6 /docker-entrypoint.sh nginx -g 'daemon off;'
或者docker image inspect 看之前的镜像,把 之前镜像的 Entrypoint的所有和 Cmd的连接起来就
能得到启动命令
#----save/load--操作镜像--
docker save -o busybox.tar busybox:latest 把busybox镜像保存成tar文件
docker load -i busybox.tar 把压缩包里面的内容直接导成镜像
#----------
镜像为什么能长久运行
镜像启动一定得有一个阻塞的进程,一直干活,在这里代理。
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
docker run --name myredis2 -p 6379:6379 -p 8888:6379 redis
镜像启动以后做镜像里面默认规定的活。
docker run -it busybox; 交互模式进入当前镜像启动的容器
---------
#----产生镜像-----
1、基于已经存在的容器,提取成镜像
2、人家给了我tar包,导入成镜像
3、做出镜像
-1)、准备一个文件Dockerfile
FROM busybox
CMD ping baidu.com
-2)、编写Dockerfile
-3)、构建镜像
docker build -t mybusy66:v6 -f Dockerfile .
#---做redis的镜像---
FROM alpine(基础镜像)
//下载安装包
//解压
//准备配置文件
CMD redis-server redis.conf
#----------
build 是根据一个Dockerfile构建出镜像
commit 是正在运行中的容器提交成一个镜像
# 容器的状态
Created(新建)、Up(运行中)、Pause(暂停)、Exited(退出)
docker run的立即启动,docker create得稍后自己启动
#推送镜像
注册docker hub并登录
可以创建一个仓库,选为public
docker push hzhero/mynginx:tagname
docker hub一个完整镜像的全路径是
docker.io/library/redis:alpine3.13 我们的 docker.io/hzhero/mynginx:tagname
docker images的时候镜像缩略了全名 默认官方镜像没有docker.io/library/
docker.io/ rediscommander / redis-commander:latest
docker.io/hzhero/mynginx:v4 我的镜像的全称
登录远程docker仓库
当前会话登录以后 docker login 。所有的东西都会push到这个人的仓库
docker push hzhero/mynginx:tagname
上面命令的完整版 docker push docker.io/hzhero/mynginx:v4
怎么知道是否登录了 cat ~/.docker/config.json 有没有 auth的值,没有就是没有登录
docker hub太慢了,用阿里云的镜像仓库,或者以后的habor仓库
sudo docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/hzh/mynginx:
[镜像版sudo docker push registry.cn-hangzhou.aliyuncs.com/hzh/mynginx:[镜
像版本号]
仓库网址/名称空间(hzh/hzhero)/仓库名:版本号
2、典型命令
1、docker run
常用关键参数 OPTIONS 说明:
-d: 后台运行容器,并返回容器ID;
-i: 以交互模式运行容器,通常与 -t 同时使用;
-P: 随机端口映射,容器内部端口随机映射到主机的端口
-p:指定端口映射,格式为:主机(宿主)端口:容器端口
-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用
--name="nginx-lb":为容器指定一个名称;
--dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致;
--dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致;
-h "mars": 指定容器的hostname;
-e username="ritchie": 设置环境变量;
--env-file=[]: 从指定文件读入环境变量;
--cpuset="0-2" or --cpuset="0,1,2": 绑定容器到指定CPU运行;
-m :设置容器使用内存最大值;
--net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;
--link=[]: 添加链接到另一个容器;
--expose=[]: 开放一个端口或一组端口;
--restart , 指定重启策略,可以写--restart=awlays 总是故障重启
--volume , -v: 绑定一个卷。一般格式 主机文件或文件夹:虚拟机文件或文件夹
0、如何使用Docker部署组件
1、部署Nginx
1.直接启动
docker run --name nginx -p 80:80 -d nginx
2.挂载启动
# 1.注意 宿主机的/etc/nginx/conf.d等三个目录下的内容必须存在
# 2.执行以下命令
docker run --name nginx -p 80:80 -v /etc/nginx/html:/usr/share/nginx/html:ro -v /etc/nginx/conf.d:/etc/nginx/conf.d -d nginx
3.访问nginx
curl 127.0.0.1:80
2、部署MySQL
# 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
3、部署ElasticSearch
#准备文件和文件夹,并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
4、部署Tomcat
# 考虑,如果我们每次 -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
5、部署Redis
# 提前准备好redis.conf文件,创建好相应的文件夹。目录为/app/redis/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.2.1-alpine3.13 \
redis-server /etc/redis/redis.conf --appendonly yes
docker run -p 6379:6379 --name redis \
-v /etc/redis/redis.conf:/etc/redis/redis.conf \
-v /nfs/redis/data:/data \
-d redis:6.0.18 \
redis-server /etc/redis/redis.conf --appendonly yes
6、重启策略
no,默认策略,在容器退出时不重启容器
on-failure,在容器非正常退出时(退出状态非0),才会重启容器
on-failure:3,在容器非正常退出时重启容器,最多重启3次
always,在容器退出时总是重启容器
unless-stopped,在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容
器
2、docker exec
一般用来与正在运行的容器进行交互,在容器内执行命令
$ docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
-
OPTIONS
Name, shorthand Default Description --detach
,-d
Detached mode: run command in the background --detach-keys
Override the key sequence for detaching a container --env
,-e
Set environment variables --env-file
Read in a file of environment variables --interactive
,-i
Keep STDIN open even if not attached --privileged
Give extended privileges to the command --tty
,-t
Allocate a pseudo-TTY --user
,-u
Username or UID (format: `<name --workdir
,-w
Working directory inside the container -
常用事例:
1、直接操作
docker exec -it alpine sh
2、进入容器后的指定目录
docker exec -it -w /root alpine pwd
3、docker build
docker build 命令从 Dockerfile 和“上下文”构建 Docker 镜像。构建的上下文是位于指定 PATH 或 URL 中的一组文件。构建过程可以引用上下文中的任何文件。例如,您的构建可以使用 COPY 指令在上下文中引用文件。
docker build [OPTIONS] PATH | URL | -
-
常用事例:
1、本地目录下构建
-
通过文件MyDockerfile构建镜像名字为:myImageName
docker build -t myImageName -f MyDockerfile .
2、通过URL构建
-
这将克隆 GitHub 存储库并将克隆的存储库用作上下文。存储库根目录下的 Dockerfile 用作 Dockerfile。可以使用 git:// 或 git@ 方案指定任意 Git 存储库
docker build github.com/creack/docker-firefox
4、docker push
上传镜像到仓库
docker push [OPTIONS] NAME[:TAG]
-
OPTIONS
Name, shorthand Default Description --all-tags
,-a
Push all tags of an image to the repository --disable-content-trust
true
Skip image signing --quiet
,-q
Suppress verbose output -
常用事例
1、上传本地镜像myapache:v1到指定镜像仓库中。
docker push myapache:v1 registry-host:5000/myadmin/myapache:v1
2、 也可以通过tag命令预先指定镜像名称和版本号,优势是多版本推送
# 1、本地预先打标签
docker image tag myimage registry-host:5000/myname/myimage:latest
docker image tag myimage registry-host:5000/myname/myimage:v1.0.1
docker image tag myimage registry-host:5000/myname/myimage:v1.0
docker image tag myimage registry-host:5000/myname/myimage:v1
# 2、查看
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
myimage latest 6d5fcfe5ff17 2 hours ago 1.22MB
registry-host:5000/myname/myimage latest 6d5fcfe5ff17 2 hours ago 1.22MB
registry-host:5000/myname/myimage v1 6d5fcfe5ff17 2 hours ago 1.22MB
registry-host:5000/myname/myimage v1.0 6d5fcfe5ff17 2 hours ago 1.22MB
registry-host:5000/myname/myimage v1.0.1 6d5fcfe5ff17 2 hours ago 1.22MB
# 3、通过-a 或 --all-tags 推送
docker image push --all-tags registry-host:5000/myname/myimage