记录docker概念,安装及入门日常使用
Docker安装(Linux / Debian)
查看官方文档,在Debian上安装Docker,其他平台在这里查阅,以下均在root
用户下操作,省去sudo
命令
卸载旧版本
apt-get remove docker docker-engine docker.io containerd runc
/var/lib/docker/
目录会保留images, containers, volumes, and networks这些旧版本文件
添加Docker存储库
更新apt
包索引
apt-get update
检查必要安装依赖软件https
apt-get install apt-transport-https ca-certificates curl gnupg2 software-properties-common
添加Docker的官方GPG密钥:
curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
执行上述命令,输出OK后,接下来根据这个密钥9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
的最后8个字符,进行校验拥有的密钥
apt-key fingerprint 0EBFCD88
pub rsa4096 2017-02-22 [SCEA]
9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid [ unknown] Docker Release (CE deb)
sub rsa4096 2017-02-22 [S]
查看主机操作系统位数(指令集)及Debian发行版的名称
⇒ uname -a
Linux hwyun01 4.9.0-9-amd64 #1 SMP Debian 4.9.168-1+deb9u3 (2019-06-16) x86_64 GNU/Linux
⇒ lsb_release -cs
stretch
可见我的操作系统是x86_64/amd64
的,发行版是stretch
。记住这个,方便接下来设置对应仓库
设置稳定版仓库
x86_64/amd64
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"armhf 设置仓库
add-apt-repository "deb [arch=armhf] https://download.docker.com/linux/debian $(lsb_release -cs) stable"arm64 设置仓库
add-apt-repository "deb [arch=arm64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"apt安装Docker
- 更新
apt
包索引apt-get update
- 安装最新版本的Docker社区版
apt-get install docker-ce docker-ce-cli containerd.io
-
通过运行hello-world 映像验证是否正确安装
docker run hello-world
apt安装成功service启动失败处理
作者安装时候遇到报错如下:
Error starting daemon: Error initializing network controller: error obtaining controller instance: failed to create NAT chain DOCKER: iptables failed: iptables --wait -t nat -N DOCKER: iptables v1.4.21: can't initialize iptables table `nat': Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.
经检查iptables
是最新的,却无法正常使用,所以只能尝试通过更新内核来解决问题,最后确实是内核问题。
作者通过此文章Debian 9更新到最新的Linux内核更新内核
Docker卸载
卸载软件
apt-get purge docker-ce
删除所有图像,容器和卷
rm -rf /var/lib/docker
systemd管理Docker
- 状态:
systemctl status docker.service
- 开启:
systemctl start docker.service
- 关闭:
systemctl stop docker.service
- 重启:
systemctl restart docker.service
- 开机启动:
systemctl enable docker.service
- 取消开机启动:
systemctl disable docker.service
检测Docker
docker --version
查看版本
docker --version
Docker version 19.03.1, build 74b1e89
docker info
查看版本更多详细信息
docker info
Client:
Debug Mode: false
Server:
Containers: 1
Running: 0
Paused: 0
......
拉取及运行hello-world检测是否运行正常
docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:451ce787d12369c5df2a32c85e5a03d52cbcef6eb3586dd03075f3034f10adcd
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
......
Docker基本概念
- Image:镜像,一个应用及其环境打包成静态模板文件,类似系统被刻录成一个GHOST/ISO文件,或者Java里面的一个类文件
- Container:容器,根据镜像创建的运行实例,就如GHOST文件被拷贝解压安装到系统,或类被
new
实例化成一个实例对象,有一个属性active=1或active=0代表运行是否激活运行 - Repository:仓库,我们获取镜像的地方,好比apt安装的source.list定义的软件地址。Docker中仓库有官方的Docker Hub,国内网易,中科大等。创建或修改
/etc/docker/daemon.json
,配置该json即可修改源
Docker操作
Repository(仓库)
仓库在/etc/docker/daemon.json
配置,默认安装完后是没有的,需要创建这个json。现在将仓库指向官方中国:https://registry.docker-cn.com
⇒ cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
⇒ systemctl status docker.service
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2019-08-22 18:01:36 CST; 6s ago
Docs: https://docs.docker.com
Main PID: 7650 (dockerd)
......
Image(镜像)
镜像是应用及其运行环境打包成的一个特殊文件,镜像是静态文件,构建打包后就不更改,是一个模板文件。
对镜像可以操作的命令
使用docker image --help
可以查看对镜像的所有命令,如下
⇒ docker image --help
Usage: docker image COMMAND
Manage images
Commands:
build Build an image from a Dockerfile
history Show the history of an image
import Import the contents from a tarball to create a filesystem image
inspect Display detailed information on one or more images
load Load an image from a tar archive or STDIN
ls List images
prune Remove unused images
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rm Remove one or more images
save Save one or more images to a tar archive (streamed to STDOUT by default)
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
Run 'docker image COMMAND --help' for more information on a command.
查看已存在镜像列表
如上所示,docker image ls
是列出镜像列表
⇒ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest fce289e99eb9 7 months ago 1.84kB
从仓库下载拉取镜像
如上所示,docker image pull
是列出镜像列表,该命令等价于docker pull
,下面以拉取tomcat
为例子,docker pull tomcat
获取最新的tomcat
镜像,其他版本的在这里找到(https://hub.docker.com/_/tomcat)[https://hub.docker.com/_/tomcat]这里查看
如需获取指定tag
为8.5.45
的镜像则执行docker pull tomcat:8.5.45
⇒ docker pull tomcat # 此处获取最新tomcat镜像
Using default tag: latest
latest: Pulling from library/tomcat
9cc2ad81d40d: Pull complete
e6cb98e32a52: Pull complete
ae1b8d879bad: Pull complete
42cfa3699b05: Pull complete
8d27062ef0ea: Pull complete
9b91647396e3: Pull complete
7498c1055ea3: Pull complete
a183d8c2c929: Pull complete
73dd800dda4c: Pull complete
2bc71ef979ec: Pull complete
Digest: sha256:80db17f3efd9cdcd9af7c799097fe0d223bbee8f25aa36234ab56292e3d8bd7b
Status: Downloaded newer image for tomcat:latest
docker.io/library/tomcat:latest
⇒ docker pull tomcat:8.5.45 # 此处获取指定版本的tomcat镜像
8.5.45: Pulling from library/tomcat
Digest: sha256:80db17f3efd9cdcd9af7c799097fe0d223bbee8f25aa36234ab56292e3d8bd7b
Status: Downloaded newer image for tomcat:8.5.45
docker.io/library/tomcat:8.5.45
根据以上的sha256
可见,这两个tomcat
镜像实际上是一样的,而上面这些9cc2ad81d40d: Pull complete
,e6cb98e32a52: Pull complete
是构建tomcat的基础层,由于两个tomcat是一样的,所以第二个tomcat拉取的时候,就不再重复获取基础层了
现在查看存在的镜像
⇒ docker images # 等价docker image ls命令
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat 8.5.45 96c4e536d0eb 10 hours ago 506MB
tomcat latest 96c4e536d0eb 10 hours ago 506MB
hello-world latest fce289e99eb9 7 months ago 1.84kB
注意:后文
IMAGE_ID
指的是镜像ID,IMAGE_NAME
指的是镜像名称,tag
指的是镜像标签,[]
指的是可选项,如[:tag]
指的是可选择添加:tag
这个参数
官方教程:docker image
根据镜像进行创建且运行容器
使用docker run
用于根据镜像,创建或启动时为其提供的配置,而创建的一个实例。就好比一个系统重装系统时候,开始配置了一些设置,这个系统就是根据这些配置而独特存在。也好比一个类被new
初始化时候set了很多参数,有一个属性active=1代表运行情况,是一个独特的类实例。
现在【后台运行
】我们的【tomcat
】镜像,容器【名称叫my-tomcat
】,映射宿主主机【8010
端口到容器8080
端口】(tomcat绑定容器的端口)
⇒ docker run --name my-tomcat -p 8010:8080 -d tomcat:latest
4101c6ff59a7b72fac6523fee002ac3efa36512a2cdcb76a096b51aed0b1aefb
打开浏览器,访问主机IP:8010
即可访问这个名称为my-tomcat
的tomcat
了,具体参数在容器节点详细介绍
官方教程:docker run
删除镜像
dockere image rm IMAGE_ID/IMAGE_NAME[:tag]
和docker rmi IMAGE_ID/IMAGE_NAME[:tag]
均可以删除镜像。但是删除的镜像IMAGE_ID
必须没有对应的实例(实例不管运行情况)
⇒ docker images # 查看所有镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat 8.5.45 96c4e536d0eb 15 hours ago 506MB
tomcat latest 96c4e536d0eb 15 hours ago 506MB
hello-world latest fce289e99eb9 7 months ago 1.84kB
⇒ docker rmi 96c4e536d0eb #删除tomcat和tomcat:8.5.45镜像,这个镜像被关联了ID为4101c6ff59a7的容器
Error response from daemon: conflict: unable to delete 96c4e536d0eb (cannot be forced) - image is being used by running container 4101c6ff59a7
⇒ docker ps -a # 查看所有容器
CONTAINER ID IMAGE ...... NAMES
4101c6ff59a7 tomcat:latest ...... my-tomcat
3c1dc4f3a8a5 hello-world ...... pedantic_boyd
⇒ docker stop my-tomcat && docker rm my-tomcat # 删除并且停止容器
my-tomcat
my-tomcat
⇒ docker rmi 96c4e536d0eb # 根据镜像ID删除,提示对应多个而冲突,
Error response from daemon: conflict: unable to delete 96c4e536d0eb (must be forced) - image is referenced in multiple repositories
⇒ docker rmi tomcat #默认删除tag为latest的tomcat
Untagged: tomcat:latest
⇒ docker images # 再次查看Docker镜像,已经删除了
REPOSITORY TAG IMAGE ID CREATED SIZE
tomcat 8.5.45 96c4e536d0eb 15 hours ago 506MB
hello-world latest fce289e99eb9 7 months ago 1.84kB
官方教程:docker rmi
Container(容器)
容器,根据镜像创建的运行实例,就如GHOST文件被拷贝解压安装到系统,或类文件被new
实例化成一个实例。实例的情况可以是运行和停止,对比一个系统的开机关机,Java类中实例状态是不是被激活的(有一个属性active=1)
运行容器
这里重点说明一些常用的参数
- -d,指定容器运行于前台还是后台,默认为false
- -i,以交互模式运行容器,通常与 -t 同时使用
- -t,为容器重新分配一个伪输入终端,通常与 -i 同时使用
- -p,指定端口映射,格式为:
主机(宿主)端口:容器端口
- --name "XXX":为容器指定一个"XXX"名称;
- -v:宿主主机挂载绑定到容器的文件,格式为:
主机(宿主)目录:容器目录
- -w:设置是容器初始化后运行的工作的目录
再次【后台运行
】我们的【tomcat
】镜像,容器【名称叫my-tomcat
】,映射宿主主机【8010
端口到容器8080
端口】,将宿主主机目录【/opt/temp/my-tomcat-home
挂载到容器/home/
】将tomcat文件只不过刚刚删除了tomcat:latest
镜像,这次使用tomcat:8.5.45
镜像运行
⇒ docker run --name my-tomcat -p 8010:8080 -v /opt/temp/my-tomcat-home/:/home/ -d tomcat:8.5.45
9d8b94aa10f16bb8fabdcc88cda5545babdb45de8fd8da5e9d1a3141252eb115
9d8b94aa10f16bb8fabdcc88cda5545babdb45de8fd8da5e9d1a3141252eb115
这个是这个tomcat
容器的ID
,可以通过这个ID
来管理容器,也可以使用my-tomcat
这个别名来管理
注意:如果不以-d
后台运行,则CTRL+C
中断日志打印后,这个容器将自动停止和退出
官方教程:docker run
如下定义:
CONTAINER_ID
指的是容器ID,CONTAINER_NAME
指的是容器初始化的--name参数指定的名称别名
查看容器运行情况
docker ps
和docker container ls
均可以查看在运行的容器,添加-a
参数可以查看所有容器,包括已经停止的容器
⇒ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4101c6ff59a7 tomcat:latest "catalina.sh run" 2 minutes ago Up 2 minutes 0.0.0.0:8010->8080/tcp my-tomcat
官方教程:docker ps
查看容器日志
docker log
命令可以查看容器打印的全部日志,添加--follow
可以以追踪方式(类似tail -f
)进行查看持续日志
⇒ docker logs --follow my-tomcat
22-Aug-2019 14:37:09.877 INFO [main] ...... Server version: Apache Tomcat/8.5.45
22-Aug-2019 14:37:09.879 INFO [main] ...... Server built: Aug 14 2019 22:21:25 UTC
22-Aug-2019 14:37:09.880 INFO [main] ...... Server number: 8.5.45.0
22-Aug-2019 14:37:09.880 INFO [main] ...... OS Name: Linux
22-Aug-2019 14:37:09.880 INFO [main] ...... OS Version: 4.19.0-0.bpo.5-amd64
22-Aug-2019 14:37:09.880 INFO [main] ...... Architecture: amd64
22-Aug-2019 14:37:09.881 INFO [main] ...... Java Home: /usr/local/openjdk-8/jre
......
22-Aug-2019 14:40:29.023 INFO [main] ...... Starting ProtocolHandler ["http-nio-8080"]
22-Aug-2019 14:40:29.034 INFO [main] ...... Starting ProtocolHandler ["ajp-nio-8009"]
22-Aug-2019 14:40:29.037 INFO [main] ...... Server startup in 199069 ms
官方教程:docker logs
进入容器操作系统
docker exec -it CONTAINER_ID COMMAND
可以进入容器,该命令后面必须接入两个参数,指定的容器CONTAINER_ID
和执行的命令COMMAND
如docker exec -it my-tomcat /bin/bash
,
⇒ docker exec -it my-tomcat /bin/bash
root@6a894561ef38:/usr/local/tomcat# pwd
/usr/local/tomcat
root@6a894561ef38:/usr/local/tomcat# java -version
openjdk version "1.8.0_222"
OpenJDK Runtime Environment (build 1.8.0_222-b10)
OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)
官方教程:docker exec
宿主主机与容器文件交互
挂载
my-tomcat
按照/opt/temp/my-tomcat-home
挂载到容器/home/
进行初始化时候,已经挂载了目录。
⇒ echo hello docker > temp/my-tomcat-home/volume-test.txt # 主机文件
⇒ cat temp/my-tomcat-home/volume-test.txt
hello docker
⇒ docker exec -it my-tomcat /bin/bash # 进入容器
root@804eac98d95e:/usr/local/tomcat# cat /home/volume-test.txt #容器文件
hello docker
数据拷贝
使用docker cp
命令,可以将宿主主机与容器之间进行数据拷贝,格式:
- docker cp CONTAINER:SRC_PATH DEST_PATH|-
- docker cp SRC_PATH|- CONTAINER:DEST_PATH
# 准备数据
⇒ mkdir -p /opt/cp-test
⇒ echo hello docker > /opt/cp-test/info.txt
⇒ cat cp-test/info.txt
hello docker
# 将主机/opt/temp/cp-test目录拷贝到容器my-tomcat的/home目录下
⇒ docker cp /opt/cp-test my-tomcat:/home/ # 复制
⇒ docker exec -it my-tomcat /bin/bash # 进入容器
root@804eac98d95e:/usr/local/tomcat# cat /home/cp-test/info.txt # 查看
hello docker
# 将主机/opt/temp/cp-test目录拷贝到容器my-tomcat,重命名为/home/new-test
⇒ docker cp /opt/cp-test my-tomcat:/home/new-test # 复制
⇒ docker exec -it my-tomcat /bin/bash # 进入容器
root@804eac98d95e:/usr/local/tomcat# cat /home/new-test/info.txt # 查看
hello docker
#将容器my-tomcat的/usr/local/tomcat/logs/目录拷贝到主机的/opt/temp/目录中。
⇒ docker cp my-tomcat:/usr/local/tomcat/logs /opt/temp/ # 复制
⇒ ls -l /opt/temp/logs # 查看
total 12
-rw-r----- 1 root root 6788 Aug 23 01:36 catalina.2019-08-22.log
-rw-r----- 1 root root 0 Aug 23 01:36 host-manager.2019-08-22.log
-rw-r----- 1 root root 459 Aug 23 01:36 localhost.2019-08-22.log
-rw-r----- 1 root root 0 Aug 23 01:36 localhost_access_log.2019-08-22.txt
-rw-r----- 1 root root 0 Aug 23 01:36 manager.2019-08-22.log
官方教程:docker start
停止容器
在删除镜像的时候已经使用过了:docker container stop
或docker stop
。好比Java类一个实例对象,设置其属性active=0,但是这个实例还是存在的,只是没有运行起来而已
⇒ docker stop my-tomcat # docker stop CONTAINER_ID/CONTAINER_NAME
my-tomcat
官方教程:docker stop
再次启动容器
docker container start
或docker start
将再次启动docker run
配置好的容器。好比Java类的一个实例对象,设置其属性active=1,代表这个对象是激活的,运行的。配置还是docker run
时候已经定义好的了,只是将之前的定义的容器,再次运行起来。
⇒ docker start my-tomcat # docker start CONTAINER_ID/CONTAINER_NAME
my-tomcat
官方教程:docker start
删除容器
在删除镜像的时候已经使用过了:docker container rm
或docker rm
。好比Java类一个实例对象,其属性active为0后,才可以且被垃圾回收器回收了
⇒ docker rm my-tomcat # docker rm CONTAINER_ID/CONTAINER_NAME
my-tomcat
官方教程:docker rm
参考
10分钟快速掌握Docker必备基础知识