Docker基础用法
1.什么是Docker
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或Windows操作系统上,也可以实现虚拟化。容器是完全使用沙箱机制,互之间不会有任何接口
2.Docker的发展史
docker本身不是容器,它只是一个更加易用的前端管理器。
最早期的容器技术概念是用chroot来实现隔离,但是chroot只是提供了对进程文件目录虚拟化的功能,不能防止进程恶意访问系统。
直到2008年 LXC(Linux Containers"牛奶牌牛奶"),一套完整的Linux容器管理实现方案,也有如别的方案如:OpenVZ等...
lxc --> libcontainer --> runC
docker在起步阶段使用lxc,但发现其并不是那么好用,于是docker公司就自己把cgroups和lxc做了一个联合封装。lxc向上提供的接口做了二次封装,使其变成更易用的容器管理界面和容器管理逻辑。从而使得整个容器的使用变得更加简便了。
容器的核心组件:
- NameSpaces :名称空间
仅能做到隔离,而不能做到资源分配的问题。PID,user,hostname,network都属于内核的,所以需要隔离开来。
rootfs: 根文件系统(mount)
PID
user
hostname /proc/system/hostname
network
ipc : 进程间通信(Inter-Process Communication)
- Control Groups: 控制组
他能够实现以进程为单位,来尝试着把我们的CPU的时间分配,用量分配,内存空间分配,IO用量分配以指定比例或指定数量的方式分派给多个进程。
3.Docker的安装
[root@zzd139 ~]# cd /etc/yum.repos.d/ [root@zzd139 yum.repos.d]# curl -o docker-ce.repo https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1919 100 1919 0 0 14992 0 --:--:-- --:--:-- --:--:-- 14992 [root@zzd139 yum.repos.d]# sed -i 's@https://download.docker.com@https://mirrors.tuna.tsinghua.edu.cn/docker-ce@g' docker-ce.repo [root@zzd139 yum.repos.d]# dnf -y install docker-ce [root@zzd139 ~]# systemctl enable --now docker.service Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /usr/lib/systemd/system/docker.service.
docker安装完后需要配置一个加速器,来提升镜像拉取的速度,可以注册一个阿里云,获取自己私人的加速器,然后将私人加速器写在/etc/docker/daemon.json文件中,重启docker
4.Docker的基础用法
常用操作
命令 | 功能 |
---|---|
docker search | 在Docker Hub上搜索映像 |
docker pull | 从镜像仓库中拉取镜像 |
docker images | 查看当前主机上的镜像 |
docker create | 创建一个容器 |
docker start | 启动一个或多个容器 |
docker run | 创建并启动容器 |
docker attach | 连接到一个正在运行的容器,不能执行任何命令,可以使用Ctrl+c退出,但是容器也也会被迫停止 |
docker ps | 列出正在运行的容器 |
docker logs | 查看容器日志 |
docker restart | 重启容器 |
docker stop | 停止一个或多个容器 |
docker kill | 杀死一个或多个正在运行的容器 |
docker rm | 删除一个或多个容器 |
docker exec | 进入到一个正在运行的容器里,可以给容器指定一个终端,执行部分命令 |
docker info | 显示整个docker系统的信息 |
docker inspect | 显示一个容器的的信息 |
//搜索名为httpd的镜像 [root@zzd139 ~]# docker search httpd NAME DESCRIPTION STARS OFFICIAL AUTOMATED httpd The Apache HTTP Server Project 4109 [OK] centos/httpd-24-centos7 Platform for running Apache httpd 2.4 or bui… 44 centos/httpd 35 [OK] clearlinux/httpd httpd HyperText Transfer Protocol (HTTP) ser… 2 hypoport/httpd-cgi httpd-cgi 2 [OK] solsson/httpd-openidc mod_auth_openidc on official httpd image, ve… 2 [OK] dockerpinata/httpd 1 nnasaki/httpd-ssi SSI enabled Apache 2.4 on Alpine Linux 1 lead4good/httpd-fpm httpd server which connects via fcgi proxy h… 1 [OK] inanimate/httpd-ssl A play container with httpd, ssl enabled, an… 1 [OK] publici/httpd httpd:latest 1 [OK] dariko/httpd-rproxy-ldap Apache httpd reverse proxy with LDAP authent… 1 [OK] manageiq/httpd Container with httpd, built on CentOS for Ma… 1 [OK] centos/httpd-24-centos8 1 manasip/httpd 0 amd64/httpd The Apache HTTP Server Project 0 patrickha/httpd-err 0 manageiq/httpd_configmap_generator Httpd Configmap Generator 0 [OK] paketobuildpacks/httpd 0 httpdss/archerysec ArcherySec repository 0 [OK] httpdocker/kubia 0 sandeep1988/httpd-new httpd-new 0 e2eteam/httpd 0 19022021/httpd-connection_test This httpd image will test the connectivity … 0 sherazahmedvaival/httpd-php-fpm74 0 //拉取一个httpd的镜像 [root@zzd139 ~]# docker pull httpd Using default tag: latest latest: Pulling from library/httpd a2abf6c4d29d: Pull complete dcc4698797c8: Pull complete 41c22baa66ec: Pull complete 67283bbdd4a0: Pull complete d982c879c57e: Pull complete Digest: sha256:0954cc1af252d824860b2c5dc0a10720af2b7a3d3435581ca788dff8480c7b32 Status: Downloaded newer image for httpd:latest docker.io/library/httpd:latest //查看镜像仓库,看有没有刚拉取的镜像 [root@zzd139 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE httpd latest dabbfbe0c57b 7 months ago 144MB //利用httpd镜像创建一个容器,--name可以指定容器的名称 [root@zzd139 ~]# docker create --name web1 httpd a3c0f836767cb5a37f96dcb924497651baee7c1515899bc5aed449f3c70c8d5c //启动web1这个容器 [root@zzd139 ~]# docker start web1 web1 //查看正在运行的容器 [root@zzd139 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a3c0f836767c httpd "httpd-foreground" 7 minutes ago Up About a minute 80/tcp web1 //停止web1容器 [root@zzd139 ~]# docker stop web1 web1 //-a选项是列出所有容器 [root@zzd139 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a3c0f836767c httpd "httpd-foreground" 9 minutes ago Exited (0) 10 seconds ago web1 //创建一个容器,在后台直接运行,不需要手动启动,-p选项可以做端口映射,将本地的80端口映射到容器的80端口,-d是在后台运行 [root@zzd139 ~]# docker run -d --name web2 -p 80:80 httpd 5b460bbfb25805c54a1dfd1a077d47b6db54eb91086703ef84028107f4fb1af3 [root@zzd139 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5b460bbfb258 httpd "httpd-foreground" 6 seconds ago Up 5 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp web2 //进行访问 [root@zzd139 ~]# curl 127.0.0.1 <html><body><h1>It works!</h1></body></html> //查看容器web2的日志 [root@zzd139 ~]# docker logs web2 AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message [Sun Aug 07 03:35:06.306670 2022] [mpm_event:notice] [pid 1:tid 140021497249088] AH00489: Apache/2.4.52 (Unix) configured -- resuming normal operations [Sun Aug 07 03:35:06.307379 2022] [core:notice] [pid 1:tid 140021497249088] AH00094: Command line: 'httpd -D FOREGROUND' 172.17.0.1 - - [07/Aug/2022:03:37:12 +0000] "GET / HTTP/1.1" 200 45 //重启web2 [root@zzd139 ~]# docker restart web2 web2 [root@zzd139 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5b460bbfb258 httpd "httpd-foreground" 5 minutes ago Up 2 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp web2 //杀死web2容器 [root@zzd139 ~]# docker kill web2 web2 [root@zzd139 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5b460bbfb258 httpd "httpd-foreground" 6 minutes ago Exited (137) 4 seconds ago web2 a3c0f836767c httpd "httpd-foreground" 23 minutes ago Exited (0) 13 minutes ago web1 //删除docker上的所有容器,-f可以强制删除正在运行的容器,-q可以显示容器的id,然后通过容器的id进行删除操作 [root@zzd139 ~]# docker rm -f $(docker ps -aq) 5b460bbfb258 a3c0f836767c [root@zzd139 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES //如果是删除镜像的话可以使用docker rmi imagename //进入到一个容器,并给容器一个终端,可以执行部分Linux命令 //先创建一个容器并运行 [root@zzd139 ~]# docker run -d --name web1 -p 80:80 httpd ab2b72d2f1af93e6c395bbe6a6db275ccfe6ce7f1d5260f8c72c0b1a001a910b //进入容器 [root@zzd139 ~]# docker exec -it web1 /bin/bash root@ab2b72d2f1af:/usr/local/apache2# ls --color bin build cgi-bin conf error htdocs icons include logs modules root@ab2b72d2f1af:/usr/local/apache2# exit exit [root@zzd139 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ab2b72d2f1af httpd "httpd-foreground" 4 minutes ago Up 4 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp web1 //退出终端,容器也不会停止 //查看当前系统docker的信息 [root@zzd139 ~]# docker info Client: Context: default Debug Mode: false Plugins: app: Docker App (Docker Inc., v0.9.1-beta3) buildx: Docker Buildx (Docker Inc., v0.8.2-docker) scan: Docker Scan (Docker Inc., v0.17.0) Server: Containers: 1 Running: 1 Paused: 0 Stopped: 0 Images: 1 Server Version: 20.10.17 Storage Driver: overlay2 Backing Filesystem: xfs Supports d_type: true Native Overlay Diff: true userxattr: false Logging Driver: json-file Cgroup Driver: cgroupfs Cgroup Version: 1 Plugins: Volume: local Network: bridge host ipvlan macvlan null overlay Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog Swarm: inactive Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc Default Runtime: runc Init Binary: docker-init containerd version: 10c12954828e7c7c9b6e0ea9b0c02b01407d3ae1 runc version: v1.1.2-0-ga916309 init version: de40ad0 Security Options: seccomp Profile: default Kernel Version: 4.18.0-257.el8.x86_64 Operating System: CentOS Stream 8 OSType: linux Architecture: x86_64 CPUs: 1 Total Memory: 940.9MiB Name: zzd139 ID: ASEB:JPMU:TNRE:JA6K:7T5M:DJG2:OLAX:K7OW:NRQK:HZ52:7KPW:QS6C Docker Root Dir: /var/lib/docker Debug Mode: false Registry: https://index.docker.io/v1/ Labels: Experimental: false Insecure Registries: 127.0.0.0/8 Registry Mirrors: https://l3f007f6.mirror.aliyuncs.com/ Live Restore Enabled: false //查看某个容器的信息 [root@zzd139 ~]# docker inspect web1 [ { "Id": "ab2b72d2f1af93e6c395bbe6a6db275ccfe6ce7f1d5260f8c72c0b1a001a910b", "Created": "2022-08-07T04:13:23.154003477Z", "Path": "httpd-foreground", "Args": [], "State": { "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, …………
5.Docker存储驱动
docker提供了多种存储驱动来实现不同的方式存储镜像,下面是常用的几种存储驱动:
- AUFS
- OverlayFS
- Devicemapper
- Btrfs
- VFS
AUFS
AUFS(AnotherUnionFS)是一种Union FS,是文件级的存储驱动。AUFS是一个能透明覆盖一个或多个现有文件系统的层状文件系统,把多层合并成文件系统的单层表示。简单来说就是支持将不同目录挂载到同一个虚拟文件系统下的文件系统。这种文件系统可以一层一层地叠加修改文件。无论底下有多少层都是只读的,只有最上层的文件系统是可写的。当需要修改一个文件时,AUFS创建该文件的一个副本,使用CoW将文件从只读层复制到可写层进行修改,结果也保存在可写层。在Docker中,底下的只读层就是image,可写层就是Container。
AUFS文件系统据说有3W行代码,而ext4文件系统却只有4000-5000行左右代码,这些代码是要被整合进内核的,后来AUFS申请要被合并进内核代码的时候,linuz觉得它这代码太过臃肿,于是拒绝了。因此AUFS这个文件系统一直以来就不是linux内核中自有的文件系统,想用AUFS这个文件系统的话,必须自己向内核打补丁并去编译使用它,但redhat系列的操作系统一向以稳定著称,不会干这种出格的事,所以在redhat系列操作系统中使用AUFS并无可能。而ubuntu上的docker默认使用的就是AUFS。
OverlayFS
Overlay是Linux内核3.18后支持的,也是一种Union FS,和AUFS的多层不同的是Overlay只有两层:一个upper文件系统和一个lower文件系统,分别代表Docker的镜像层和容器层。当需要修改一个文件时,使用CoW将文件从只读的lower复制到可写的upper进行修改,结果也保存在upper层。在Docker中,底下的只读层就是image,可写层就是Container。目前最新的OverlayFS为Overlay2。
AUFS和Overlay都是联合文件系统,但AUFS有多层,而Overlay只有两层,所以在做写时复制操作时,如果文件比较大且存在比较低的层,则AUSF会慢一些。而且Overlay并入了linux kernel mainline,AUFS没有。目前AUFS已基本被淘汰。
DeviceMapper
Device mapper是Linux内核2.6.9后支持的,提供的一种从逻辑设备到物理设备的映射框架机制,在该机制下,用户可以很方便的根据自己的需要制定实现存储资源的管理策略。AUFS和OverlayFS都是文件级存储,而Device mapper是块级存储,所有的操作都是直接对块进行操作,而不是文件。Device mapper驱动会先在块设备上创建一个资源池,然后在资源池上创建一个带有文件系统的基本设备,所有镜像都是这个基本设备的快照,而容器则是镜像的快照。所以在容器里看到文件系统是资源池上基本设备的文件系统的快照,并没有为容器分配空间。当要写入一个新文件时,在容器的镜像内为其分配新的块并写入数据,这个叫用时分配。当要修改已有文件时,再使用CoW为容器快照分配块空间,将要修改的数据复制到在容器快照中新的块里再进行修改。
OverlayFS是文件级存储,Device mapper是块级存储,当文件特别大而修改的内容很小,Overlay不管修改的内容大小都会复制整个文件,对大文件进行修改显然要比小文件要消耗更多的时间,而块级无论是大文件还是小文件都只复制需要修改的块,并不是整个文件,在这种场景下,显然device mapper要快一些。因为块级的是直接访问逻辑盘,适合IO密集的场景。而对于程序内部复杂,大并发但少IO的场景,Overlay的性能相对要强一些。