环境:
- centos8.2 最小化安装
- docker
一、docker概念
官网:https://www.docker.com/
Github Docker 源码:https://github.com/docker/docker-ce
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版),我们用社区版就可以了。
参照:Docker 教程
二、docker安装
2.1 安装依赖
首先,安装gcc和gcc-c++:
yum -y install gcc
yum -y install gcc-c++
然后,安装其他依赖:
yum install -y yum-utils device-mapper-persistent-data lvm2
2.2 安装docker
首先,配置docker仓库地址:
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
然后,在安装之前,我们可以先搜索一下docker软件包:
[root@bogon ~]# yum list docker-ce.x86_64 --showduplicates | sort -r
docker-ce.x86_64 3:20.10.6-3.el8 docker-ce-stable
docker-ce.x86_64 3:20.10.5-3.el8 docker-ce-stable
docker-ce.x86_64 3:20.10.4-3.el8 docker-ce-stable
docker-ce.x86_64 3:20.10.3-3.el8 docker-ce-stable
docker-ce.x86_64 3:20.10.2-3.el8 docker-ce-stable
docker-ce.x86_64 3:20.10.1-3.el8 docker-ce-stable
docker-ce.x86_64 3:20.10.0-3.el8 docker-ce-stable
docker-ce.x86_64 3:19.03.15-3.el8 docker-ce-stable
docker-ce.x86_64 3:19.03.14-3.el8 docker-ce-stable
docker-ce.x86_64 3:19.03.13-3.el8 docker-ce-stable
Docker CE Stable - x86_64 2.8 kB/s | 12 kB 00:04
上次元数据过期检查:0:00:02 前,执行于 2021年05月12日 星期三 08时38分18秒。
可安装的软件包
[root@bogon ~]#
最后,直接安装最新的docker-ce即可: yum -y install docker-ce
[root@bogon ~]# yum -y install docker-ce
上次元数据过期检查:0:01:08 前,执行于 2021年05月12日 星期三 08时38分18秒。
依赖关系解决。
=============================================================================================================================================================================================
软件包 架构 版本 仓库 大小
=============================================================================================================================================================================================
安装:
docker-ce x86_64 3:20.10.6-3.el8 docker-ce-stable 27 M
升级:
libsemanage x86_64 2.9-3.el8 BaseOS 165 k
安装依赖关系:
checkpolicy x86_64 2.9-1.el8 BaseOS 348 k
...
tar x86_64 2:1.30-5.el8 BaseOS 838 k
启用模块流:
container-tools rhel8
事务概要
=============================================================================================================================================================================================
安装 20 软件包
升级 1 软件包
总下载:112 M
下载软件包:
(1/21): container-selinux-2.155.0-1.module_el8.3.0+699+d61d9c41.noarch.rpm 208 kB/s | 51 kB 00:00
...
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
总计 3.1 MB/s | 112 MB 00:36
警告:/var/cache/dnf/docker-ce-stable-fa9dc42ab4cec2f4/packages/containerd.io-1.4.4-3.1.el8.x86_64.rpm: 头V4 RSA/SHA512 Signature, 密钥 ID 621e9f35: NOKEY
Docker CE Stable - x86_64 2.6 kB/s | 1.6 kB 00:00
导入 GPG 公钥 0x621E9F35:
Userid: "Docker Release (CE rpm) <docker@docker.com>"
指纹: 060A 61C5 1B55 8A7F 742B 77AA C52F EB6B 621E 9F35
来自: https://download.docker.com/linux/centos/gpg
导入公钥成功
运行事务检查
事务检查成功。
运行事务测试
事务测试成功。
运行事务
准备中 : 1/1
安装 : docker-scan-plugin-0.7.0-3.el8.x86_64
...
已升级:
libsemanage-2.9-3.el8.x86_64
已安装:
checkpolicy-2.9-1.el8.x86_64 container-selinux-2:2.155.0-1.module_el8.3.0+699+d61d9c41.noarch containerd.io-1.4.4-3.1.el8.x86_64
docker-ce-3:20.10.6-3.el8.x86_64 docker-ce-cli-1:20.10.6-3.el8.x86_64 docker-ce-rootless-extras-20.10.6-3.el8.x86_64
docker-scan-plugin-0.7.0-3.el8.x86_64 fuse-common-3.2.1-12.el8.x86_64 fuse-overlayfs-1.3.0-2.module_el8.3.0+699+d61d9c41.x86_64
fuse3-3.2.1-12.el8.x86_64 fuse3-libs-3.2.1-12.el8.x86_64 libcgroup-0.41-19.el8.x86_64
libslirp-4.3.1-1.module_el8.3.0+475+c50ce30b.x86_64 policycoreutils-python-utils-2.9-9.el8.noarch python3-audit-3.0-0.17.20191104git1c2f876.el8.x86_64
python3-libsemanage-2.9-3.el8.x86_64 python3-policycoreutils-2.9-9.el8.noarch python3-setools-4.3.0-2.el8.x86_64
slirp4netns-1.1.8-1.module_el8.3.0+699+d61d9c41.x86_64 tar-2:1.30-5.el8.x86_64
完毕!
[root@bogon ~]#
2.3 启动docker
systemctl start docker
# 或
systemctl start docker.service
注意: 如果没有启动docker就运行docker命令,可能会提示: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
另附常用命令:
# 启动docker服务
systemctl stop docker.service
# 重启docker服务
systemctl restart docker.service
2.4 查看docker安装的版本:
[root@bogon ~]# clear
[root@bogon ~]# docker --version
Docker version 20.10.6, build 370c289
[root@bogon ~]# docker version
Client: Docker Engine - Community
Version: 20.10.6
API version: 1.41
Go version: go1.13.15
Git commit: 370c289
Built: Fri Apr 9 22:44:36 2021
OS/Arch: linux/amd64
Context: default
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 20.10.6
API version: 1.41 (minimum version 1.12)
Go version: go1.13.15
Git commit: 8728dd2
Built: Fri Apr 9 22:43:02 2021
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.4.4
GitCommit: 05f951a3781f4f2c1911b05e61c160e9c30eaa8e
runc:
Version: 1.0.0-rc93
GitCommit: 12644e614e25b05da6fd08a38ffa0cfe1903fdec
docker-init:
Version: 0.19.0
GitCommit: de40ad0
[root@bogon ~]#
三、Docker镜像、容器和仓库
DockerHub地址:https://hub.docker.com/
-
镜像:类似于操作系统中安装的软件(存在于硬盘中,未运行)。
-
容器:类似于操作系统中的进程(从安装的软件运行)。
注意:它是一个虚拟化的沙箱,如果容器里运行了一个redis,我们运行时需要手动将redis的对外接口暴露出去,这样外面才能访问。还有,对于每个容器它都有自己的localhost和127.0.0.1,所以在涉及ip地址时要格外小心。
-
仓库:docker为了方便大家共享打包好的镜像,搞了一个hub,类似于java中的maven、js中的npm、.net中的nuget。
我们不仅可以从里面拉取别人已经打包好的镜像,还可以自己注册账号上传。
当然,我们也可以仅本地打包镜像自己用,不上传到hub,并且从hub上拉取的镜像会被缓存到本地。
镜像的版本控制:
每个镜像都有一个tag来标识镜像的版本,这样我们安装时就可以指定特别版本的镜像。不过,遗憾的是,docker的搜索结果中并没有显示tag(后面自己写脚本实现)。
下面以redis为例,说下docker命令的使用:
3.1 从DockerHub中搜索可用的Redis镜像:docker search redis
[root@bogon ~]# docker search redis
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
redis Redis is an open source key-value store that… 9417 [OK]
bitnami/redis Bitnami Redis Docker Image 178 [OK]
sameersbn/redis 83 [OK]
grokzen/redis-cluster Redis cluster 3.0, 3.2, 4.0, 5.0, 6.0, 6.2 78
rediscommander/redis-commander Alpine image for redis-commander - Redis man… 58 [OK]
redislabs/redisearch Redis With the RedisSearch module pre-loaded… 34
redislabs/redisinsight RedisInsight - The GUI for Redis 30
redislabs/redis Clustered in-memory database engine compatib… 29
oliver006/redis_exporter Prometheus Exporter for Redis Metrics. Supp… 25
redislabs/rejson RedisJSON - Enhanced JSON data type processi… 23
arm32v7/redis Redis is an open source key-value store that… 23
bitnami/redis-sentinel Bitnami Docker Image for Redis Sentinel 21 [OK]
redislabs/redisgraph A graph database module for Redis 15 [OK]
redislabs/redismod An automated build of redismod - latest Redi… 12 [OK]
arm64v8/redis Redis is an open source key-value store that… 12
webhippie/redis Docker images for Redis 11 [OK]
insready/redis-stat Docker image for the real-time Redis monitor… 10 [OK]
s7anley/redis-sentinel-docker Redis Sentinel 10 [OK]
circleci/redis CircleCI images for Redis 7 [OK]
centos/redis-32-centos7 Redis in-memory data structure store, used a… 5
clearlinux/redis Redis key-value data structure server with t… 3
tiredofit/redis Redis Server w/ Zabbix monitoring and S6 Ove… 1 [OK]
wodby/redis Redis container image with orchestration 1 [OK]
runnable/redis-stunnel stunnel to redis provided by linking contain… 1 [OK]
xetamus/redis-resource forked redis-resource 0 [OK]
[root@bogon ~]#
3.2 查看redis官方镜像的版本
上面搜索的结果中有一个官方的镜像:“redis”,但是没有显示tag列表,下面我们自己制作脚本实现:
- 在目录
/bin
目录下创建文件docker-search-show-tag.sh
,内容如下:#!/bin/sh # # Simple script that will display docker repository tags. # # Usage: # $ docker-show-repo-tags.sh ubuntu centos for Repo in $* ; do curl -s -S "https://registry.hub.docker.com/v2/repositories/library/$Repo/tags/" | \ sed -e 's/,/,\n/g' -e 's/\[/\[\n/g' | \ grep '"name"' | \ awk -F\" '{print $4;}' | \ sort -fu | \ sed -e "s/^/${Repo}:/" done
- 赋予这个脚本可执行权限:
chmod 744 /bin/docker-search-show-tag.sh
[root@bogon ~]# chmod 744 /bin/docker-search-show-tag.sh
使用上面的脚本,展示镜像redis
的所有版本:
[root@bogon ~]# docker-search-show-tag.sh redis
redis:6.0
redis:6.0-buster
redis:6.0.13
redis:6.0.13-buster
redis:6.2
redis:6.2-buster
redis:6.2.3
redis:6.2.3-buster
redis:buster
redis:latest
[root@bogon ~]#
上面列出了很多tag(版本),注意到:里面有个latest,从字面上里面这个版本应该是代表最新的,而事实上这个标签也是一个普通的标签,只不过名字有点特殊(注意:一旦下载到本地,它就属于本地了,不会在每次运行时从远程自动更新。。。)。
另外,大家都约定这个版本的镜像应该始终保持最新,所以我们可以拉取、手动更新这个版本来让我们的程序保持最新;
3.3 安装redis镜像 & 查看本地已存在的镜像
安装最新的redis镜像:docker pull redis
安装指定版本的镜像:docker pull redis:6.0
安装最新的redis镜像时如下:
[root@bogon ~]# docker pull redis
Using default tag: latest
latest: Pulling from library/redis
f7ec5a41d630: Pull complete
a36224ca8bbd: Pull complete
7630ad34dcb2: Pull complete
e74b2f747260: Pull complete
ebc61c7bf222: Pull complete
1aafd9c07208: Pull complete
Digest: sha256:6cddb3822e19f09a6a369c35680562ddd2e44bd3bfd6fe25ec6456c42f45728b
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest
[root@bogon ~]#
可以看到,由于没有指定安装的tag,docker-cli会有一个确认的过程,直接回车即可。
安装好后,运行docker images
查看本地的镜像列表:
[root@bogon ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest ccee4cdf984f 8 days ago 105MB
[root@bogon ~]#
上面显示我们已安装了redis最新版本,但这个版本具体是redis哪个版本呢?我们可以使用如下命令:
[root@bogon ~]# docker image inspect redis:latest | grep -i version
"GOSU_VERSION=1.12",
"REDIS_VERSION=6.2.3",
"DockerVersion": "19.03.12",
"GOSU_VERSION=1.12",
"REDIS_VERSION=6.2.3",
[root@bogon ~]#
我们可以知道,当前下载的lastest版本的redis其实就是6.2.3版本的。
当然,我们可以下载时手动指定镜像版本:
[root@bogon ~]# docker pull redis:6.0
6.0: Pulling from library/redis
f7ec5a41d630: Already exists
a36224ca8bbd: Already exists
7630ad34dcb2: Already exists
b794377c17d4: Pull complete
a134ee7a12b3: Pull complete
ab302c2d25fc: Pull complete
Digest: sha256:dee031783fcbe8b5d9056303091043f1023853d73dfd3a83c7802c5038ad6f84
Status: Downloaded newer image for redis:6.0
docker.io/library/redis:6.0
[root@bogon ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
redis 6.0 3038fc9615f1 8 days ago 104MB
redis latest ccee4cdf984f 8 days ago 105MB
[root@bogon ~]#
3.4 运行redis容器
执行如下命令,将redis跑起来:docker run -it --name="redistest" -p 6379:6379 redis:6.0
运行后,我们就可以从外面访问它了(linux为虚拟机,本地物理机为:window10):
上面的命令可以让我们以阻塞的方式运行redis,但更多的时候我们是想以后台方式运行redis,重新运行以下命令:
[root@bogon ~]# docker run -d --name="redistest2" -p 16379:6379 redis:6.0
2420c44f4576cd9d66980b2eb7a3cdba39a0413353e07a0e9c09299145a498d5
[root@bogon ~]#
上面命令执行完成后,返回的是redis容器id。
我们再用redis客户端连接下:
3.5 redis容器的启动、停止 & 查看redis容器
查看正在运行的容器命令:docker ps
[root@bogon ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2420c44f4576 redis:6.0 "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 0.0.0.0:16379->6379/tcp, :::16379->6379/tcp redistest2
d7fa06746181 redis:6.0 "docker-entrypoint.s…" 9 minutes ago Up 9 minutes 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp redistest
[root@bogon ~]#
如果想暂停某个容器(redistest),可以使用如下命令:
[root@bogon ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2420c44f4576 redis:6.0 "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 0.0.0.0:16379->6379/tcp, :::16379->6379/tcp redistest2
d7fa06746181 redis:6.0 "docker-entrypoint.s…" 9 minutes ago Up 9 minutes 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp redistest
[root@bogon ~]# docker stop redistest
redistest
[root@bogon ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2420c44f4576 redis:6.0 "docker-entrypoint.s…" 5 minutes ago Up 5 minutes 0.0.0.0:16379->6379/tcp, :::16379->6379/tcp redistest2
[root@bogon ~]#
如果我们想查看所有的容器(包括停止和运行的),如下:
[root@bogon ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2420c44f4576 redis:6.0 "docker-entrypoint.s…" 6 minutes ago Up 6 minutes 0.0.0.0:16379->6379/tcp, :::16379->6379/tcp redistest2
d7fa06746181 redis:6.0 "docker-entrypoint.s…" 12 minutes ago Exited (0) About a minute ago redistest
[root@bogon ~]#
上面显示的Exited (0) About a minute ago
就表示redistest
容器已经于1分钟前停止运行了。
我们可以使用如下命令将它重新运行:
[root@bogon ~]# docker start redistest
redistest
[root@bogon ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2420c44f4576 redis:6.0 "docker-entrypoint.s…" 8 minutes ago Up 8 minutes 0.0.0.0:16379->6379/tcp, :::16379->6379/tcp redistest2
d7fa06746181 redis:6.0 "docker-entrypoint.s…" 14 minutes ago Up 2 seconds 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp redistest
[root@bogon ~]#
关于docker run命令:
上面docker run命令常用的参数
-it
:表示以交互方式运行容器(临时用,一般使用后台运行方式);
-d
:表示以后台方式运行容器;
--name
:运行的容器名称,
如:
docker run -it --name="redistest" -p 6379:6379 redis
表示运行后的容器名称为redistest
。
-p
:表示对外暴露的接口,
如:
docker run -it --name="redistest" -p 16379:6379 redis
表示容器运行后,将内部程序的6379
端口以16379
对外提供。
如果有多个端口,如下:-p 16379:6379 -p 80:80
。
如果想暴露连续的端口,如下:-p 9600-9700:9600-9700
,参考:https://www.cnblogs.com/zhzhlong/p/12581934.html
-e
:表示容器的环境变量,
如,运行asp.net core程序时,我们想指定运行的环境为
Development
,那么可以使用如下命令:
docker -e "ASPNETCORE_ENVIRONMENT=FatA" -d --name="coreweb" -p 5000:5000 coreweb
如果有多个环境变量,如下:
docker -e "ASPNETCORE_ENVIRONMENT=FatA" -e "env_test=tag" -d --name="coreweb" -p 5000:5000 coreweb
-v
: 给容器挂载存储卷,挂载到容器的某个目录,
如,我们可以使用此参数手动指定docker容器内的时区设置,如下:
docker -e "ASPNETCORE_ENVIRONMENT=FatA" -v /etc/localtime:/etc/localtime -d --name="coreweb" -p 5000:5000 coreweb
上面的命令,我们指定docker容器中的时区使用linux机器的时区设置。
3.6 移除镜像和容器
-
移除镜像:
docker rmi redis:6.0
移除之前,我们必须首先移除这个镜像的所有实例(容器),包括正在运行的和已经停止的。
-
移除容器:
docker rmi redistest
移除之前,我们必须先停止此容器。
-
移除已经停止的容器:
docker container prune