Docker
简介:
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。
Docker 使用客户端-服务器 (C/S) 架构模式 使用远程API来管理和创建Docker容器。Docker 容器(Container)通过 Docker 镜像(Image)来创建,二者之间的关系类似于面向对象编程中的对象与类
组成:
那Docker由什么组成呢, 包括三个基本概念:
- 仓库(Repository)
- 镜像(Image)
- 容器(Container)
容器:
一种虚拟化的方案(一种虚拟技术区别于传统的虚拟机)
操作系统级别的虚拟化
只能运行在相同或相似内核的操作系统
依赖于Linux内核特性:Namespace和Cgroups(ControlGroup)---缺点
安装
在 Linux 上安装 Docker
我的linux系统是阿里云服务器,是centos 7版本的。
前置条件
64-bit 系统
kernel 3.10+
用uname -r命令检查内核版本,返回的值大于3.10即可。
- 卸载旧程序
$ sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
- 安装Docker
$ sudo yum install docker
- 启动Docker
$ sudo systemctl start docker
- 测试:通过运行hello-world 映像来验证是否正确安装了Docker Engine 。
$ sudo docker run hello-world
[root@VM_0_2_centos /]# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Already exists
Digest: sha256:6a65f928fb91fcfbc963f7aa6d57c8eeb426ad9a20c7ee045538ef34847f44f1
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:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
[root@VM_0_2_centos /]#
- 用docker version命令查看docker版本
[root@VM_0_2_centos /]# docker version
Client: Docker Engine - Community
Version: 19.03.9
API version: 1.40
Go version: go1.13.10
Git commit: 9d988398e7
Built: Fri May 15 00:25:27 2020
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 19.03.9
API version: 1.40 (minimum version 1.12)
Go version: go1.13.10
Git commit: 9d988398e7
Built: Fri May 15 00:24:05 2020
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.2.13
GitCommit: 7ad184331fa3e55e52b890ea95e65ba581ae3429
runc:
Version: 1.0.0-rc10
GitCommit: dc9208a3303feef5b3839f4323d9beb36df0a9dd
docker-init:
Version: 0.18.0
GitCommit: fec3683
[root@VM_0_2_centos /]#
- docker info查看docker存储位置
- Docker 配置加速器
这里使用的是阿里云的镜像加速器
Docker 镜像命令操作
以 NGINX 为例,镜像名后跟随版本号,不然默认下载最新版本
- 搜索镜像
docker search nginx
[root@lucky ~]# docker search nginx
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 13255 [OK]
jwilder/nginx-proxy Automated Nginx reverse proxy for docker con… 1812 [OK]
richarvey/nginx-php-fpm Container running Nginx + PHP-FPM capable of… 775 [OK]
linuxserver/nginx An Nginx container, brought to you by LinuxS… 113
- 下载镜像
docker pull nginx
[root@VM_0_2_centos /]# docker pull nginx:1.17.10
1.17.10: Pulling from library/nginx
afb6ec6fdc1c: Pull complete
b90c53a0b692: Pull complete
11fa52a0fdc0: Pull complete
Digest: sha256:30dfa439718a17baafefadf16c5e7c9d0a1cde97b4fd84f63b69e13513be7097
Status: Downloaded newer image for nginx:1.17.10
docker.io/library/nginx:1.17.10
- 查询所有镜像
docker images
[root@VM_0_2_centos /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx 1.17.10 9beeba249f3e 13 days ago 127MB
centos latest 470671670cac 4 months ago 237MB
elasticsearch latest 5acf0e8da90b 20 months ago 486MB
- 删除镜像
docker rmi imageID/REPOSITORY(镜像ID/名称)
[root@VM_0_2_centos /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx 1.17.10 9beeba249f3e 13 days ago 127MB
centos latest 470671670cac 4 months ago 237MB
elasticsearch latest 5acf0e8da90b 20 months ago 486MB
[root@VM_0_2_centos /]# docker rmi 470671670cac
Untagged: centos:latest
Untagged: centos@sha256:fe8d824220415eed5477b63addf40fb06c3b049404242b31982106ac204f6700
Deleted: sha256:470671670cac686c7cf0081e0b37da2e9f4f768ddc5f6a26102ccd1c6954c1ee
Deleted: sha256:0683de2821778aa9546bf3d3e6944df779daba1582631b7ea3517bb36f9e4007
[root@VM_0_2_centos /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx 1.17.10 9beeba249f3e 13 days ago 127MB
elasticsearch latest 5acf0e8da90b 20 months ago 486MB
-
删除全部镜像
docker rmi $(docker images -q)
-
启动镜像生成容器
docker run -it nginx:1.17.10 /bin/bash
docker run是运行容器的命令,上面用到的参数意义如下:
- 这是两个参数,一个是-i交互式操作,一个是-t终端。我们这里打算进入bash 执行一些命令并查看返回结果,因此我们需要交互式终端
- nginx:1.17.10 :这是指用 nginx:1.17.10 镜像为基础来启动容器
- /bin/bash:docker后台必须运行一个进程,否则容器就会退出,在这里表示启动容器后启动bash。
进入容器后,我们可以通过shell执行任何所需要的命令,最后我们通过exit退出这个容器。
也可通过 Ctrl + p + q 退出容器
Docker 容器操作命令
- 查看所有正在运行的容器
docker ps
[root@VM_0_2_centos /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6d222ff9b93c nginx:1.17.10 "/bin/bash" 4 minutes ago Up 4 minutes 80/tcp mystifying_golick
- 停止运行的容器
docker stop image ID(容器ID)
[root@VM_0_2_centos /]# docker stop 6d222ff9b93c
6d222ff9b93c
-
停止运行所有可查询到的容器
docker stop $(docker ps -aq)
-
查询所有停止运行的容器
docker ps -a
[root@VM_0_2_centos /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6d222ff9b93c nginx:1.17.10 "/bin/bash" 6 minutes ago Exited (0) 39 seconds ago mystifying_golick
1448e803cc3f bf756fb1ae65 "/hello" 54 minutes ago Exited (0) 54 minutes ago modest_elgamal
dc6d937ffd4b bf756fb1ae65 "/hello" 56 minutes ago Exited (0) 56 minutes ago zealous_neumann
4afbf37a3765 bf756fb1ae65 "/hello" 57 minutes ago Exited (0) 57 minutes ago zen_solomon
- 启动已停止的容器
docker start imageID(容器ID)
[root@VM_0_2_centos /]# docker start 6d222ff9b93c
6d222ff9b93c
[root@VM_0_2_centos /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6d222ff9b93c nginx:1.17.10 "/bin/bash" 9 minutes ago Up 3 seconds 80/tcp mystifying_golick
- 进入正在运行的容器
docker attach imageID
ls : 查看当前目录下的所有 ls -l / ll 竖向查看
[root@VM_0_2_centos /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6d222ff9b93c nginx:1.17.10 "/bin/bash" 24 minutes ago Up 14 minutes 80/tcp mystifying_golick
[root@VM_0_2_centos /]# docker attach 6d222ff9b93c
root@6d222ff9b93c:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@6d222ff9b93c:/# ls -l
total 64
drwxr-xr-x 2 root root 4096 May 14 14:50 bin
drwxr-xr-x 2 root root 4096 May 2 16:39 boot
drwxr-xr-x 5 root root 360 May 29 12:23 dev
drwxr-xr-x 1 root root 4096 May 29 12:14 etc
drwxr-xr-x 2 root root 4096 May 2 16:39 home
drwxr-xr-x 1 root root 4096 May 15 20:15 lib
drwxr-xr-x 2 root root 4096 May 14 14:50 lib64
drwxr-xr-x 2 root root 4096 May 14 14:50 media
drwxr-xr-x 2 root root 4096 May 14 14:50 mnt
drwxr-xr-x 2 root root 4096 May 14 14:50 opt
dr-xr-xr-x 116 root root 0 May 29 12:23 proc
drwx------ 1 root root 4096 May 29 12:20 root
drwxr-xr-x 3 root root 4096 May 14 14:50 run
drwxr-xr-x 2 root root 4096 May 14 14:50 sbin
drwxr-xr-x 2 root root 4096 May 14 14:50 srv
dr-xr-xr-x 13 root root 0 May 29 11:17 sys
drwxrwxrwt 1 root root 4096 May 15 20:15 tmp
drwxr-xr-x 1 root root 4096 May 14 14:50 usr
drwxr-xr-x 1 root root 4096 May 14 14:50 var
- 删除容器
docker rm imageID(容器ID) : 启动中的容器不能删除
[root@VM_0_2_centos /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6d222ff9b93c nginx:1.17.10 "/bin/bash" 13 minutes ago Up 4 minutes 80/tcp mystifying_golick
1448e803cc3f bf756fb1ae65 "/hello" About an hour ago Exited (0) About an hour ago modest_elgamal
dc6d937ffd4b bf756fb1ae65 "/hello" About an hour ago Exited (0) About an hour ago zealous_neumann
4afbf37a3765 bf756fb1ae65 "/hello" About an hour ago Exited (0) About an hour ago zen_solomon
[root@VM_0_2_centos /]# docker rm 4afbf37a3765
4afbf37a3765
[root@VM_0_2_centos /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6d222ff9b93c nginx:1.17.10 "/bin/bash" 13 minutes ago Up 4 minutes 80/tcp mystifying_golick
1448e803cc3f bf756fb1ae65 "/hello" About an hour ago Exited (0) About an hour ago modest_elgamal
dc6d937ffd4b bf756fb1ae65 "/hello" About an hour ago Exited (0) About an hour ago zealous_neumann
- 删除所有停止运行的容器
docker rm $(docker ps -aq)
[root@VM_0_2_centos /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6d222ff9b93c nginx:1.17.10 "/bin/bash" 14 minutes ago Up 5 minutes 80/tcp mystifying_golick
1448e803cc3f bf756fb1ae65 "/hello" About an hour ago Exited (0) About an hour ago modest_elgamal
dc6d937ffd4b bf756fb1ae65 "/hello" About an hour ago Exited (0) About an hour ago zealous_neumann
[root@VM_0_2_centos /]# docker rm $(docker ps -aq)
1448e803cc3f
dc6d937ffd4b
Error response from daemon: You cannot remove a running container 6d222ff9b93c3fadd2d387e8179e4c634ca00e3494e667ce3abb5186dc3689ab. Stop the container before attempting removal or force remove
[root@VM_0_2_centos /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6d222ff9b93c nginx:1.17.10 "/bin/bash" 14 minutes ago Up 5 minutes 80/tcp mystifying_golick
Docker数据管理
docker在容器中管理数据主要有两种方式:
-
数据卷(Volumes)
-
挂载主机目录(Bind mounts)
数据卷
数据卷是一个可供容器使用的特殊目录,它绕过文件系统,可以提供很多有用的特性:
- 数据卷可以在容器之间共享和重用
- 对数据卷的修改会立马生效
- 对数据卷的更新,不会影响镜像
- 卷会一直存在,直到没有容器使用
创建数据卷
docker volume create mydata(名称)
[root@VM_0_2_centos /]# docker volume create mydata
mydata
[root@VM_0_2_centos /]# docker volume ls
DRIVER VOLUME NAME
local 7da31459c5972fcae9af9bb339c00084fcb9dad590e7c608d3d636a958fac247
local mydata
- 查看具体数据卷信息
docker volume inspect mydata(名称)
[root@VM_0_2_centos /]# docker volume inspect mydata
[
{
"CreatedAt": "2020-05-29T20:50:34+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/mydata/_data",
"Name": "mydata",
"Options": {},
"Scope": "local"
}
]
注:Mountpoint为数据在本机存储的位置,如果磁盘存储空间不足可修改此位置
- 列出数据卷列表
docker volume ls
[root@VM_0_2_centos ~]# docker volume ls
DRIVER VOLUME NAME
local 7da31459c5972fcae9af9bb339c00084fcb9dad590e7c608d3d636a958fac247
local mydata
- 删除指定数据卷
docker volume rm volume_name (名称)
[root@VM_0_2_centos ~]# docker volume ls
DRIVER VOLUME NAME
local 7da31459c5972fcae9af9bb339c00084fcb9dad590e7c608d3d636a958fac247
local mydata
[root@VM_0_2_centos ~]# docker volume rm mydata
mydata
[root@VM_0_2_centos ~]# docker volume ls
DRIVER VOLUME NAME
local 7da31459c5972fcae9af9bb339c00084fcb9dad590e7c608d3d636a958fac247
[root@VM_0_2_centos ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 a4fdfd462add 8 days ago 448MB
nginx 1.17.10 9beeba249f3e 2 weeks ago 127MB
centos latest 470671670cac 4 months ago 237MB
elasticsearch latest 5acf0e8da90b 20 months ago 486MB
[root@VM_0_2_centos ~]# docker run --name mysql01 -d -p 9100:3306 -v /home/lucky/volume-test:/home mysql:5.7
15f5f72beb3715efa92ac95e0c35ce7da9f7dbe441e352b8d2ee073be7b8fb52
使用 MySQL 5.7 版本镜像创建名为 MySQL01 的容器,
-d : 守护模式启动
-p : 暴露端口 9100(对外使用9100代替原来的3306)
将主机的 / home/lucky/volume-test 与容器中的 /home 映射
:如果没有此目录会被创建
挂载
方式一:直接使用命令来挂载
docker run -it 主机目录:容器目录
# 容器中添加 ceshi.sh 文件
[root@VM_0_2_centos lucky]# docker run -it -v /home/lucky/ceshi:/home centos /bin/bash
[root@5ec00a74380e /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@5ec00a74380e /]# cd /home
[root@5ec00a74380e home]# ls
[root@5ec00a74380e home]# touch ceshi.sh
[root@5ec00a74380e home]# ls
ceshi.sh
[root@5ec00a74380e home]#
使用 docker inspect 容器 id 查看挂载信息
# 容器中的文件同步到主机中
[root@VM_0_2_centos ~]# cd /home/lucky/ceshi
[root@VM_0_2_centos ceshi]# ls
ceshi.sh
[root@VM_0_2_centos ceshi]#
# 在主机中修改文件信息
[root@VM_0_2_centos /]# cd /home/lucky/ceshi
[root@VM_0_2_centos ceshi]# ls
ceshi.sh
[root@VM_0_2_centos ceshi]# vim ceshi.sh
[root@VM_0_2_centos ceshi]# cat ceshi.sh
hello my first test
[root@VM_0_2_centos ceshi]#
容器中的文件也被同步
# 退出容器并将容器停止运行
[root@a790e015183e home]# exit
exit
[root@VM_0_2_centos /]# docker stop a790e015183e
a790e015183e
再次将主机中文件信息修改
# 重新启动并进入容器中查看,文件依然被同步
[root@VM_0_2_centos /]# docker start a790e015183e
a790e015183e
[root@VM_0_2_centos /]# docker attach a790e015183e
[root@a790e015183e /]# cd /home
[root@a790e015183e home]# ls
ceshi.sh
[root@a790e015183e home]# cat ceshi.sh
hello my first test
this is second
[root@a790e015183e home]#
# 删除容器
[root@VM_0_2_centos /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5ec00a74380e centos "/bin/bash" 2 minutes ago Exited (127) 22 seconds ago angry_neumann
[root@VM_0_2_centos /]# docker rm 5ec00a74380e
5ec00a74380e
[root@VM_0_2_centos /]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@VM_0_2_centos /]#
# 主机中的文件依然存在
[root@VM_0_2_centos ceshi]# ls
ceshi.sh
方式二:
docker run --name xxxx -p 8888:8888 --mount type:volume,source=/src/xxx,target=/xxx /my:/docker -it imagename /bin/bash
type选项,其可以是bind,volume,或 tmpfs。本主题讨论卷,因此类型始终是 volume
注意:使用-v参数时如果本地目录不存在Docker会自动为你创建一个文件夹。使用–mount参数时如果本地目录不存在,Docker会报错。Docker挂载主机目录的默认权限是读写,用户也可以通过增加readonly指定为只读。
- 如果挂载一个空的数据卷到容器中的一个非空目录中,那么这个目录下的文件会被复制到数据卷中。(我的测试:使用 -v 参数并没有这个效果,需要使–mount参数,如果不符请指正)
- 如果挂载一个非空的数据卷到容器中的一个目录中,那么容器中的目录中会显示数据卷中的数据。如果原来容器中目录非空,那么这些原始数据会被隐藏掉。
Dockerfile
关于Dockerfile
在Docker中创建镜像最常用的方式,就是使用Dockerfile。Dockerfile是一个Docker镜像的描述文件,我们可以理解成火箭发射的A、B、C、D…的步骤。Dockerfile其内部包含了一条条的指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
Dockerfile常用指令
FROM
scratch是虚拟的镜像,表示一个空白的镜像,也是最为基础的镜像。
MAINTAINER
指明镜像维护着及其联系方式(一般是邮箱地址):
lucky < xxxxxxxx@xx.com >
RUN
构建镜像时运行的Shell命令
shell 格式: RUN <命令> ,RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
exec 格式: RUN ["可执行文件", "参数1", "参数2"] 。run可以写多个,每一个指令都会建立一层,所以正确写法应该是↓
RUN buildDeps='gcc libc6-dev make' \
&& apt-get update \
&& apt-get install -y $buildDeps \
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" \
&& mkdir -p /usr/src/redis \
&& tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \
&& make -C /usr/src/redis \
&& make -C /usr/src/redis install \
&& rm -rf /var/lib/apt/lists/* \
&& rm redis.tar.gz \
&& rm -r /usr/src/redis \
&& apt-get purge -y --auto-remove $buildDeps
ADD
拷贝文件或目录到镜像中
ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /
<源路径> 可以是一个 URL ,下载后的文件权限自动设置为 600 。
ADD html.tar.gz /var/www/html
ADD https://xxx.com/html.tar.gz /var/www/html
PS : 如果是URL或压缩包,会自动下载或自动解压
WORKDIR
为RUN、CMD、ENTRYPOINT以及COPY和AND设置工作目录
WORKDIR <工作目录路径>
RUN cd /app
RUN echo "hello" > world.txt
两次run不在一个环境内,可以使用WORKDIR。
VOLUME
指定容器挂载点到宿主机自动生成的目录或其他容器
VOLUME ["/var/lib/mysql"]
EXPOSE
声明容器运行的服务端口
EXPOSE <端口1> [<端口2>...]
EXPOSE :EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射。
CMD
启动容器时执行的Shell命令
shell 格式: CMD <命令>
exec 格式: CMD ["可执行文件", "参数1", "参数2"...]
CMD ["nginx", "-g", "daemon off;"]
ENV
在其他指令中可以直接引用ENV设置的环境变量。
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
示例:
ENV VERSION=1.0 DEBUG=on NAME="Happy Feet"
案例
使用 vim dockerfile 创建并编辑文件
FROM centos
MAINTANIER www.edisonchou.com
ADD jdk-8u45-linux-x64.tar.gz /usr/local
ENV JAVA_HOME /usr/local/jdk1.8.0_45
ADD apache-tomcat-8.0.46.tar.gz /usr/local
COPY server.xml /usr/local/apache-tomcat-8.0.46/conf
RUN rm -f /usr/local/*.tar.gz
WORKDIR /usr/local/apache-tomcat-8.0.46
EXPOSE 8080
ENTRYPOINT ["./bin/catalina.sh", "run"]
CMD "----end----"
使用 docker build -f dockerfile -t lucky/mytomcat:v1(这是定义 tag 的版本号信息) 构建镜像
运行镜像生成容器
docker run -it --name mytomcat1 -p 9100:8080 -d 6d279e252e0b
进入容器查看
docker exec -it mytomcat /bin/bash
CMD和ENTRYPOINT区别
CMD 会覆盖只会执行最后一条,如果运行时有其他命令会覆盖
# 文件执行后用 ls-a 进行查询
CMD ["ls","-a"]
如
docker run -it mytomcat -l
会将 CMD 覆盖 变成 -l
ENTRYPOINT 则会在后进行追加
ENTRYPOINT ["ls","-a"]
ls -al
将镜像发布到阿里云
创建自己的镜像仓库
剩下按照步骤即可上传
入门就到这里吧。