docker基础
docker
主要就是了解一下docker和虚拟机的区别
docker原理
docker常见的操作
1、docker和虚拟机的区别
1、操作系统的组成部分
-
内核空间:
-
进程管理
-
驱动管理
-
还有其他的
-
-
用户空间:
-
shell 命令行管理
-
GUI 图形化界面管理
-
-
系统调用指的就是使用shell或者其他的调用内核的一些参数
2、容器和虚拟机的区别
-
容器:
-
容器的操作系统是一个阉割版的操作系统,只包含操作系统的用户空间,以及要部署的软件和相关的依赖
-
一台宿主机上面的所有容器都共用同一个宿主机内核
-
性能更高,隔离性差
-
容器提供应用级别的服务
-
redis镜像
-
mysql镜像
-
nginx镜像
-
-
容器就是为了任务而生的
-
-
虚拟机
-
虚拟机是一个完整的操作系统
-
较大的性能损耗
-
提供Iass层服务镜像
-
ubuntu 22.04镜像
-
centos 7 镜像
-
-
-
虚拟化层级
-
docker:操作系统虚拟化,利用宿主机的操作系统内核,通过这个容器引擎创建隔离的用户空间,所有容器共享同一个内核,只需要安装对应的程序和依赖项即可
-
虚拟机:硬件虚拟化,通过hypervisor(vmware,virtualbox,kvm)模拟完整的硬件环境,虚拟机控制器,每一个虚拟机都有独立的操作系统内核,驱动程序和应用程序
-
-
资源占用
-
docker: 容器共享内核,不需要额外的操作系统的开销,资源占用少,启动速度快
-
虚拟机:每个虚拟机都包含完整的操作系统,资源占用大,启动速度慢
-
-
性能:
-
docker: 由于直接利用宿主机的内核和硬件资源,性能接近原生应用程序
-
虚拟机:由于Hypervisor层的存在,以及每个虚拟机都需要运行独立的操作系统,性能有一定损耗。
-
-
隔离性:
-
Docker:容器之间的隔离是基于Linux内核的命名空间(Namespaces)和控制组(cgroups),隔离性相对较弱,但足够满足大多数应用场景。如果一个容器被攻破,可能会影响其他容器。
-
虚拟机:每个虚拟机都运行独立的操作系统,隔离性强。一个虚拟机被攻破不会影响其他虚拟机。
-
-
移植性:
-
Docker:通过Docker镜像,可以轻松地在不同环境中部署相同的应用,实现"一次构建,到处运行"。
-
虚拟机:虚拟机镜像通常依赖于特定的Hypervisor和硬件配置,移植性较差。
-
-
应用场景:
- Docker:适合微服务架构、持续集成/持续部署(CI/CD)、开发测试环境隔离等场景。
-虚拟机:适合需要完全隔离的应用,如多租户环境、遗留应用迁移、不同操作系统共存等场景。
2、docker安装和工作原理
-
二进制安装
-
yum安装

-
是一个c/s架构
-
客户端线程本地拉取镜像,没有的话,从镜像仓库里面进行拉取
-
通过这个docker的守护进程管理容器
2、docker镜像
1、镜像的命名规则
-
registry/namespace/image:tag
-
docker.io/libary/httpd:latest
-
regitry: 仓库地址
-
namespace: 命名空间,里面存储镜像
-
image: 镜像的名字
-
tag: 镜像标签,镜像版本
-
-
就是一个仓库(registry),里面有不同的房间(namespace),不同的房间存储不同的货物(image)
-
不需要加上https:// docker默认加上了
2、镜像管理
# 列出本地镜像
docker images
# 拉取镜像
docker pull 镜像
# 删除镜像
docker rmi 镜像
# -f 强制删除镜像,就是这个容器正在使用这个镜像
# 但是了,不会删除掉容器
3、镜像仓库
-
有dockerhub 或者私有仓库
-
比如在华为云,阿里云上面搭建自己的镜像仓库
# 首先登陆镜像仓库
docker login 华为云/阿里云
# 为镜像重新命名
# 符合这个仓库的命名规则,才能将自己的镜像推送上去
# 在华为云上面创建组织(命名空间)
docker tag httpd:latest 镜像仓库地址/命名空间/image:tag
# 推送镜像
docker push 镜像
4、镜像加速器
- 设置了镜像加速器的话,就从这个里面拉取镜像即可
{
"registry-mirrors": ["镜像加速器"]
}
3、容器管理
1、运行容器
- tid选项
# t 就是分配一个终端tty
# i 交互式
# d 放在后台运行,不占用前台的终端
# /bin/sh 给了这个容器一个任务
[root@server docker]# docker run -tid --name b1 busybox:latest /bin/sh
# 不给任务的的话,执行容器的默认任务(命令) sh
[root@server docker]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5b27e6539ea4 busybox:latest "sh" 2 seconds ago Up 1 second b2
c0b790da860e busybox:latest "/bin/sh" 4 minutes ago Up 4 minutes b1
- exec 进入容器
# /bin/sh 分配了一个终端才能进入
[root@server docker]# docker exec -ti b1 /bin/sh
/ # ls
bin dev etc home lib lib64 proc root sys tmp usr var
/ #
# 退出这个容器,容器不会停止,因为分配了一个终端,不会覆盖容器默认的命令
2、端口映射
- 容器是为了一个任务而生的,因此运行一个nginx容器提供网页,容器创建出来有自己的ip地址,相关的资源
# 运行了一个容器,查看ip地址为172.17.0.2
[root@server ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7af8f33f1c72 nginx:latest "/docker-entrypoint.…" 40 seconds ago Up 39 seconds 80/tcp elastic_babbage
# 在宿主机上面进行访问
[root@server ~]# curl 172.17.0.2
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
# 但是了跨主机是访问不到的,客户端访问不到的,因此需要做端口映射才行
- 因此的话,就需要这个端口映射,端口映射就能实现外部直接访问宿主机的ip+端口就能访问到容器内部运行的服务了
# -p 宿主机端口:容器端口
# 将8080端口映射到容器内部的80端口上了
[root@server ~]# docker run -tid -p 8080:80 nginx
a2f6386e1aa06a9d9602eb9bc9a907ccd78e48bb375f775f1280c870a36bd9c7
do[root@server ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a2f6386e1aa0 nginx "/docker-entrypoint.…" 4 seconds ago Up 3 seconds 0.0.0.0:8080->80/tcp distracted_keller
7af8f33f1c72 nginx:latest "/docker-entrypoint.…" 4 minutes ago Up 4 minutes 80/tcp elastic_babbage
# -P 将容器的端口随机映射到宿主机上面

- 这个端口映射的原理
# 做了一个DNA
# 访问宿主机的8080端口转发到容器内部的80端口上了
iptables -t nat -L -n
Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 to:172.17.0.3:80
3、环境变量
就是有些容器启动的时候,需要传入环境变量才能启动的
- 例如这个mysql容器,启动的时候,必须添加数据库的密码才行
[root@server /]# docker run -tid --name m1 -e MYSQL_ROOT_PASSWORD=123 uhub.service.ucloud.cn/qwimages/mysql:latest
[root@server /]# mysql -uroot -p123 -h 172.17.0.2 -P3306
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 9.5.0 MySQL Community Server - GPL
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>
4、docker存储
创建一个容器出来,我们在容器里面进行的操作,写入等等都是写入到一个临时的存储空间上面,删除容器的时候,镜像还是存在的,删除的是容器的临时空间
如果是存储数据库的文件的话,删除的话,就找不到了
因此的话就有了持久化存储了
常见的是目录挂载,可以指定读写权限,将宿主机的目录挂载到容器内部的存储数据的目录上即可
如果宿主机目录不存在的话,会自动的创建,容器里面也是这样的
[root@server ~]# docker run -tid --name n1 -v /root/index.html:/usr/share/nginx/html/index.html -P nginx
f5fa405252c44165f8a39f8dc374025af8926b2f3d595385a8ae2c70a30e1766
[root@server ~]# curl localhost:32768
123
# 修改这个index.html 容器里面的数据也会被修改
但是了,如果在容器里面进行删除的话,那么这个宿主机上面的数据也会被删除,因此的添加一个ro权限
[root@server ~]# docker run -tid --name n2 -v /tmp/:/data:ro nginx
d0d59ece9b88c8c7b4777c6c4d83edc8286ee89efe338e70e9bb339464048a8c
[root@server ~]# docker exec -ti n2 /bin/bash
root@d0d59ece9b88:/# cd /data/
root@d0d59ece9b88:/data# ls
systemd-private-ed558b8db37947e99aab459f3f501e69-chronyd.service-8SlgwA
systemd-private-ed558b8db37947e99aab459f3f501e69-systemd-logind.service-cALe9S
# 写入不了文件,只读的挂载
root@d0d59ece9b88:/data# echo 13 > 1.txt
bash: 1.txt: Read-only file system
# 但是宿主机可以修改
卷挂载,匿名卷和命名卷
默认创建出来的卷就是匿名卷
指定卷的名字就是命名卷
5、docker网络
安装docker的时候,已经创建出来一个默认的网桥docker0
这个网桥会自动的为创建出来的容器分配ip地址,充当这个dhcp的作用
# 网段是172.0.0.1
[root@server /]# ifconfig docker0
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:9bff:fe2c:45f2 prefixlen 64 scopeid 0x20<link>
ether 02:42:9b:2c:45:f2 txqueuelen 0 (Ethernet)
RX packets 81 bytes 9769 (9.5 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 107 bytes 10031 (9.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
host网络模式,直接使用宿主机的网络,性能是最高的
缺点就是会占用宿主机的端口,容器造成端口冲突
# 查看网络信息,直接宿主机的网络
[root@server /]# docker run -tid --name b1 --network host busybox:latest
da3d2f5e2febfcde888c0228078f4a9b1fc56f48c3a4f6b07b6e2a54435da02c
[root@server /]# docker exec -ti b1 /bin/sh
/ # ifconfig
docker0 Link encap:Ethernet HWaddr 02:42:9B:2C:45:F2
inet addr:172.17.0.1 Bcast:172.17.255.255 Mask:255.255.0.0
inet6 addr: fe80::42:9bff:fe2c:45f2/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:83 errors:0 dropped:0 overruns:0 frame:0
TX packets:109 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:9825 (9.5 KiB) TX bytes:10115 (9.8 KiB)
ens33 Link encap:Ethernet HWaddr 00:0C:29:FE:CB:8E
inet addr:192.168.50.20 Bcast:192.168.50.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fefe:cb8e/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:209671 errors:0 dropped:0 overruns:0 frame:0
TX packets:24711 errors:0 dropped:0 overruns:0 carrier:0
bridge网络模式是最常见的,可以进行端口映射,nat转发,但是了在传输的过程中性能会有损耗
# 指定网段,网关
docker network create --driver bridge --subnet 173.0.0.0/24 --gateway 173.0.0.1 b1
[root@server /]# docker network ls
NETWORK ID NAME DRIVER SCOPE
70e7306eb9cd b1 bridge local
111a03cb769c bridge bridge local
f70c061fd48b host host local
fbe5deb122ae none null local
docker run -tid --name b1 --network b1 busybox
# 2个网段之间的通信的话,就需要一个容器连接另外一个网桥才能实现通信
docker network connect bridge b1
net.ipv4.ip_forward = 1 这个内核参数需要开启,ipv4转发的参数
6、docker-compose
容器编排工具,将创建容器的相关的命令都存储在这个文件上面
非常的便捷
能够同时启动多个容器,对多个容器进行操作
- 一个实验wordpress
[root@server mnt]# cat wordpress.yml
version: "2.2" # 版本需要指定,不同的版本支持不同的参数,不添加这个的话,默认使用的是version1版本的,
services: # 服务名
wordpress: # 第一个容器
image: uhub.service.ucloud.cn/qwimages/wordpress:latest
container_name: web # 指定容器的名字
ports: # 指定容器的端口
- "8080:80"
links: # 给容器起一个别名,db是容器名,web-db是容器的别名
- db:web-db
depends_on: # 先启动哪一个容器,自己才能启动
- db
environment: # 环境变量
- WORDPRESS_DB_HOST=web-db # 连接数据库地址
- WORDPRESS_DB_USER=root # 连接数据库用户名
- WORDPRESS_DB_PASSWORD=root # 连接数据库的密码
- WORDPRESS_DB_NAME=wordpress # 连接数据库的库
db:
image: uhub.service.ucloud.cn/qwimages/mysql:latest
container_name: d1
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=root # 数据库的密码
- MYSQL_DATABASE=wordpress # 创建的数据库
# 启动容器,指定yaml文件
docker-compose -f wordpress.yml up -d
# 删除容器,会删除容器的卷,网络信息
[root@server mnt]# docker-compose -f wordpress.yml down -v
Stopping web ... done
Stopping d1 ... done
Removing web ... done
Removing d1 ... done
Removing network mnt_default
7、容器的生命周期
- 创建,启动,暂停,退出,删除
6、问题排查
有的时候,容器会出现问题,就需要进行排查
docker inspect container_id 查看errors字段,如果没有的话,就是正常的退出,而不是这个容器自身的原因了
docker logs container_id 查看容器的日志信息
总结
- podman docker-podman 用docker来管理podman

浙公网安备 33010602011771号