建议先收藏,有需要就拿出来,耐心看,一定有所收获,好东西都需要时间去付出得来的。
产生背景:
(1)开发和运维、测试因为环境不同而导致的矛盾(操作系统不同、软件环境不同、应用配置的不同等)
(2)集群环境下每台服务器都需要配置相同的环境,成本巨大
(3)充分利用服务器机器的资源,避免浪费
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口
沙箱:
为运行中的程序提供的隔离环境。通常是作为一些来源不可信、具破坏力或无法判定程序意图的程序提供实验之用。
作用:
(1)将软件环境安装并且配置好,打包成一个镜像image,然后将该镜像发布出去(docker仓库)。
其他使用者可以在仓库中下载并使用这个镜像,通过docker运行这个镜像,可以获取相同的环境。
(2)简化环境部署和配置,实现一次构建,处处运行。
Docker相比于传统虚拟化方式具有更多的优势:
特性 | 容器 | 虚拟机 |
---|---|---|
启动 | 秒级 | 分钟级 |
硬盘使用 | 一般为MB | 一般为GB |
性能 | 接近原生 | 弱于 |
系统支持量 | 单机支持上千个容器 | 一般是几十个 |
从上图我们可以看到,Docker 中包括三个基本的概念:
简要概括就是:
Image(镜像):将软件环境打包好的模板,用来创建容器,一个镜像可以创建N个容器
Container(容器):镜像运行后产生的实例称为容器,每运行一次镜像就会产生一个容器,容器之间相互是隔离的。
Repository(仓库):用来保存镜像,仓库中含有许多的镜像,每个镜像都有不同的标签tag。
详细概括就是:
镜像是 Docker 运行容器的前提,仓库是存放镜像的场所,可见镜像更是 Docker 的核心。
Image (镜像)
镜像是静态的、可以被用户互相分享的文件。我们玩过双系统和虚拟机的人都知道,首先你需要一个.iso镜像,才能安装系统。Docker中的镜像也是这个东西,镜像是静态的,你不能对他操作,只能pull别人的镜像或者push自己的镜像。
Docker镜像可以看作是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
容器(Container)
前面说过,镜像是静态不可操作的,只能被分享和下载,那什么是能被操作的呢?就是容器里!容器可以理解为镜像的动态状态,也就是我们虚拟机中系统装好后的状态,如果要保存修改,就需要将当前容器封装成一个新的镜像,这样下次启动这个新的镜像后之前作出的修改还都在。
仓库(Repository)
Docker中的仓库很像git的代码仓库,你可以pull自己之前push到自己仓库的镜像到本地,也可以pull别人push到公共仓库的镜像到自己本地。说白了就是百度云盘,你可以上传(push)自己做好环境的Docker上去,也可以下载(pull)自己云端的镜像到本地。同时,我们知道百度云最大的特点就是分享,类比Docker,如果你得到百度云分享链接(别人的镜像名字、标签和别人的用户名),你还可以下载(pull)别人分享的镜像到自己的本地,别人也可以下载(pull)你的镜像,因为Docker仓库都是公共的。当然,每个免费用户有一个名额把自己的一个镜像设为私有,也就是禁止被分享给别人,类比百度云上你自己保存的后没有去生成分享链接
Docker 的安装和使用有一些前提条件,主要体现在体系架构和内核的支持上。对于体系架构,Docker 只支持的 X86-64,目前不支持X86 ,其他体系架构的支持则一直在不断地完善和推进中。
Docker 分为 CE 和 EE 两大版本。 CE 即社区版, EE 即企业版(付费)。
我们在安装前可以参看官方文档获取最新的 Docker 支持情况,官方文档在这里:
https://docs.docker.com/install/
Docker 对于内核支持的功能,即内核的配置选项也有一定的要求(比如必须开启 Cgroup 和 Namespace 相关选项,以及其他的网络和存储驱动等), Docker 源码中提供了一个检测脚本来检测和指导内核的配置,脚本链接在这里:
https://raw.githubusercontent.com/docker/docker/master/contrib/check-config.sh
在满足前提条件后,安装就变得非常的简单了。
Docker CE 的安装请参考官方文档:
MacOS:https://docs.docker.com/docker-for-mac/install/
Windows:https://docs.docker.com/docker-for-windows/install/
Ubuntu:https://docs.docker.com/install/linux/docker-ce/ubuntu/
Debian:https://docs.docker.com/install/linux/docker-ce/debian/
CentOS:https://docs.docker.com/install/linux/docker-ce/centos/
Fedora:https://docs.docker.com/install/linux/docker-ce/fedora/
其他 Linux 发行版:https://docs.docker.com/install/linux/docker-ce/binaries/
这里我们以 CentOS7 作为本文的演示。
环境准备
阿里云服务器(1核2G,1M带宽)
CentOS 7.4 64位
由于 Docker-CE 支持 64 位版本的 CentOS7 ,并且要求内核版本不低于 3.10
执行以下安装命令去安装依赖包:
yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
第一种安装方式:
Docker 软件包已经包括在默认的 CentOS-Extras 软件源里。因此想要安装 docker,只需要运行下面的 yum 命令
yum install docker
第二种安装方式:
在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,CentOS 系统上可以使用这套脚本安装:
curl -fsSL get.docker.com -o get-docker.sh
sh get-docker.sh
curl -fsSL https://get.docker.com/ | sh
具体可以参看 docker-install 的脚本:
https://github.com/docker/docker-install
基本操作:
docker version #查看docker版本
systemctl start docker #启动docker
systemctl stop docker #停止docker
systemctl status docker #查看状态
systemctl restart docker #重启
systemctl enable docker #设置开机自动启动
[root@aliyun ~]# systemctl start docker
[root@aliyun ~]# systemctl status docker
[root@aliyun ~]# docker version
[root@aliyun ~]# rpm -qa | grep docker
docker-common-1.13.1-162.git64e9980.el7.centos.x86_64
docker-1.13.1-162.git64e9980.el7.centos.x86_64
docker-client-1.13.1-162.git64e9980.el7.centos.x86_64
三个都要卸载干净,卸载之后 rpm -qa | grep docker 验证
[root@aliyun ~]# yum remove docker-1.13.1-162.git64e9980.el7.centos.x86_64
Loaded plugins: fastestmirror, langpacks, product-id, search-disabled-repos, subscription-manager
This system is not registered with an entitlement server. You can use subscription-manager to register.
Resolving Dependencies
--> Running transaction check
---> Package docker.x86_64 2:1.13.1-162.git64e9980.el7.centos will be erased
--> Finished Dependency Resolution
Dependencies Resolved
=====================================================================================================================
Package Arch Version Repository Size
=====================================================================================================================
Removing:
docker x86_64 2:1.13.1-162.git64e9980.el7.centos @extras 65 M
Transaction Summary
=====================================================================================================================
Remove 1 Package
Installed size: 65 M
Is this ok [y/N]: y
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Erasing : 2:docker-1.13.1-162.git64e9980.el7.centos.x86_64 1/1
warning: /etc/sysconfig/docker-storage saved as /etc/sysconfig/docker-storage.rpmsave
Verifying : 2:docker-1.13.1-162.git64e9980.el7.centos.x86_64 1/1
Removed:
docker.x86_64 2:1.13.1-162.git64e9980.el7.centos
Complete!
[root@aliyun ~]# rpm -qa | grep docker
[root@aliyun ~]# docker
-bash: /usr/bin/docker: No such file or directory
[root@aliyun ~]# curl -fsSL https://get.docker.com/ | sh
# Executing docker install script, commit: 26ff363bcf3b3f5a00498ac43694bf1c7d9ce16c
+ sh -c 'yum install -y -q yum-utils'
Package yum-utils-1.1.31-54.el7_8.noarch already installed and latest version
+ sh -c 'yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo'
Loaded plugins: fastestmirror, langpacks, product-id, subscription-manager
This system is not registered with an entitlement server. You can use subscription-manager to register.
adding repo from: https://download.docker.com/linux/centos/docker-ce.repo
grabbing file https://download.docker.com/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
repo saved to /etc/yum.repos.d/docker-ce.repo
+ '[' stable '!=' stable ']'
+ sh -c 'yum makecache'
Loaded plugins: fastestmirror, langpacks, product-id, search-disabled-repos, subscription-manager
This system is not registered with an entitlement server. You can use subscription-manager to register.
Loading mirror speeds from cached hostfile
* base: mirrors.cloud.aliyuncs.com
* extras: mirrors.cloud.aliyuncs.com
* updates: mirrors.cloud.aliyuncs.com
base | 3.6 kB 00:00:00
docker-ce-stable | 3.5 kB 00:00:00
epel | 4.7 kB 00:00:00
extras | 2.9 kB 00:00:00
mysql-connectors-community | 2.5 kB 00:00:00
mysql-tools-community | 2.5 kB 00:00:00
mysql57-community | 2.5 kB 00:00:00
updates | 2.9 kB 00:00:00
(1/17): docker-ce-stable/x86_64/filelists_db | 21 kB 00:00:00
(2/17): docker-ce-stable/x86_64/primary_db | 45 kB 00:00:00
(3/17): epel/x86_64/prestodelta | 822 B 00:00:00
(4/17): extras/7/x86_64/filelists_db | 217 kB 00:00:00
(5/17): epel/x86_64/other_db | 3.3 MB 00:00:00
(6/17): extras/7/x86_64/other_db | 125 kB 00:00:00
(7/17): epel/x86_64/filelists_db | 12 MB 00:00:00
(8/17): docker-ce-stable/x86_64/updateinfo | 55 B 00:00:00
(9/17): mysql-connectors-community/x86_64/other_db | 15 kB 00:00:00
(10/17): mysql-connectors-community/x86_64/filelists_db | 78 kB 00:00:00
(11/17): mysql-tools-community/x86_64/other_db | 16 kB 00:00:00
(12/17): docker-ce-stable/x86_64/other_db | 114 kB 00:00:00
(13/17): updates/7/x86_64/filelists_db | 1.7 MB 00:00:00
(14/17): mysql57-community/x86_64/other_db | 56 kB 00:00:00
(15/17): updates/7/x86_64/other_db | 249 kB 00:00:00
(16/17): mysql-tools-community/x86_64/filelists_db | 246 kB 00:00:00
(17/17): mysql57-community/x86_64/filelists_db | 1.0 MB 00:00:00
Metadata Cache Created
+ '[' -n '' ']'
+ sh -c 'yum install -y -q docker-ce'
warning: /var/cache/yum/x86_64/7/docker-ce-stable/packages/docker-ce-19.03.12-3.el7.x86_64.rpm: Header V4 RSA/SHA512 Signature, key ID 621e9f35: NOKEY
Public key for docker-ce-19.03.12-3.el7.x86_64.rpm is not installed
Importing GPG key 0x621E9F35:
Userid : "Docker Release (CE rpm) "
Fingerprint: 060a 61c5 1b55 8a7f 742b 77aa c52f eb6b 621e 9f35
From : https://download.docker.com/linux/centos/gpg
If you would like to use Docker as a non-root user, you should now consider
adding your user to the "docker" group with something like:
sudo usermod -aG docker your-user
Remember that you will have to log out and back in for this to take effect!
WARNING: Adding a user to the "docker" group will grant the ability to run
containers which can be used to obtain root privileges on the
docker host.
Refer to https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface
for more information.
[root@aliyun ~]# systemctl start docker
[root@aliyun ~]# docker version
Client: Docker Engine - Community
Version: 19.03.12
API version: 1.40
Go version: go1.13.10
Git commit: 48a66213fe
Built: Mon Jun 22 15:46:54 2020
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 19.03.12
API version: 1.40 (minimum version 1.12)
Go version: go1.13.10
Git commit: 48a66213fe
Built: Mon Jun 22 15:45:28 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
阿里云镜像源配置
mkdir -p /etc/docker
vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://duvzla6d.mirror.aliyuncs.com"]
}
systemctl daemon-reload
systemctl restart docker
也可以参考其他镜像源:https://www.cnblogs.com/reasonzzy/p/11127359.html
如果是云服务器,可以使用容器镜像服务(自己的专属加速器地址),进行配置https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
通过最简单的 image 文件 hello world,感受一下 Docker 的魅力吧!
我们直接运行下面的命令,将名为 hello-world 的 image 文件从仓库抓取到本地。
docker pull library/hello-world
docker pull images 是抓取 image 文件, library/hello-world 是 image 文件在仓库里面的位置,其中 library 是 image 文件所在的组, hello-world 是 image 文件的名字。
抓取成功以后,就可以在本机看到这个 image 文件了。
docker images
如下结果:
现在,可以运行 hello-world 这个 image 文件
输出这段提示以后,hello world 就会停止运行,容器自动终止。有些容器不会自动终止,因为提供的是服务,比如Mysql镜像等。
Docker组件是如何协作运行容器
现在我们再通过hello-world这个例子来体会一下 Docker 各个组件是如何协作的。
容器启动过程如下:
我们可以通过docker images 可以查看到 hello-world 已经下载到本地
我们可以通过docker ps 或者 docker container ls 显示正在运行的容器,我们可以看到, hello-world 在输出提示信息以后就会停止运行,容器自动终止,所以我们在查看的时候没有发现有容器在运行。
我们从上面可以看出, docker 的功能是十分强大的,除此之外,我们还可以拉去一些 Ubuntu , Apache等镜像
操作 | 命令 | 说明 |
---|---|---|
查找 | docker search 关键字 | 可以在docker hub网站查看镜像详情 |
抽取 | docker pull docker pull mysql docker pull mysql:5.7 |
:版本号,如果不指定,默认是latest |
列表 | docker images | 查看本地所有的镜像 |
获取元信息 | docker inspect 镜像ID | 获取镜像元信息 |
删除 | docker rmi -f 镜像id或镜像名:版本号 | 删除本地镜像,-f表示强制删除 |
操作 | 命令 | 说明 |
---|---|---|
运行 | docker run – name 容器名 -p 宿主机端口:容器端口 -d -v -it 镜像id或镜像名:版本号 | –name指定容器名,如果不指定会自动命名 -i 以交互模式运行 –t 分配一个终端,即命令行,通常组合使用-t –p 指定端口映射,将主机的端口映射到容器内的端口 –d表示后台运行,即以守护方式运行容器 –v 指定挂载主机目录到容器目录 |
容器的列表 | docker ps docker rm -f $(docker ps -a -q) 把所有的容器都删除的命令 |
默认查看所有运行的容器(不包括已经关闭的) -a表示显示所有的容器(包括已经关闭的) -q只显示容器id号 |
启动容器 | docker start 容器id或者容器名称 | 启动容器 |
关闭容器 | docker start 容器id或者容器名称 | 关闭容器 |
日志 | docker logs 容器id或者容器名称 | 获取容器日志 |
进入容器 | docker exec -it 容器id或容器名称 /bin/bash | 进入正在运行的容器并开启一个交互模式的终端,可以在容器中执行操作 |
拷贝文件 | docker cp 主机中的文件路径 容器ID或容器名称:容器路径 docker cp 容器ID或容器名称:容器路径 主机中的文件路径 |
将宿主机中的文件拷贝到容器中; 将容器中的文件拷贝到宿主机中; |
挂载文件(防止数据丢失) | docker run --name mytomcat5 -p 8893:8080 -v /my/tomcat/data:/usr/local/tomcat/data -d tomcat | 多个-v可以挂载多个 |
获取容器元信息 | docker inspect 容器ID | 获取容器的元信息 |
以centos为例
docker search centos
docker pull centos
docker run --name mycentos1 -it centos # 更改centos:latest创建容器,并以交互模式进入容器中
#实际上是在docker容器中运行了一个最精简版本的centos系统
exit
docker ps -a
docker start mycentos1
docker stop mycentos1
docker rm mycentos1
以tomcat为例
安装tomcat并进行端口映射
端口映射
8080端口映射为8888端口。
docker search tomcat
docker pull tomcat
docker run --name mytomcat1 -p 8888:8080 -d tomcat
精简版Tomcat 压缩到webapps.dist
将webapps.dist里的内容全部移到 /usr/local/tomcat/webapps
访问:192.168.1.137:8888
docker exec -it c0bcf6ea33 /bin/bash 进入到容器
mv /usr/local/tomcat/webapps/webapps.dist/*
/usr/local/tomcat/webapps
exit 退出容器
#测试:http://宿主机地址:8888
挂载和拷贝(容器和宿主机通信)
拷贝:
运行:docker run --name mytomcat3 -8889:8080 -d tomcat
docker cp index.jsp 容器ID:容器路径 同理这两个对象可以调换
验证检查:docker exec -it 容器ID /bin/bash
exit
echo welcome to hundsun > index.jsp
docker cp index.jsp 容器id:/usr/local/tomcat/webapps/ROOT 将宿主机中的文件拷贝到容器指定的目录中
挂载:
运行:docker run --name mytomcat5 \
-p 8893:8080
-v /my/tomcat/data:/usr/local/tomcat/data
-d tomcat
通过-v参数,冒号前为宿主机目录,必须为绝对路径,冒号后为镜像内挂载的路径。默认挂载的路径权限为读写。如果指定为只读可以用:ro -v /my/tomcat/data:/usr/local/tomcat/data:ro
docker run :根据镜像创建一个容器并运行一个命令,操作的对象是 镜像;
docker exec :在运行的容器中执行命令,操作的对象是 容器。
docker -h 去查看命令的详细的帮助文档
docker update --restart=always redis # 设置镜像容器自启动
docker rmi 镜像名/镜像ID
docker restart [-i] 容器名/容器ID ## 重启容器
docker stop 容器名/容器ID (发送信号,等待停止)## 停止容器
docker kill 容器名/容器ID(直接停止)## 立即停止容器
拉取一个 docker 镜像
docker pull image_name
// image_name 为镜像的名称,而如果我们想从 Docker Hub 上去下载某个镜像,我们可以使用以下命令:
docker pull centos:latest
// centos:lastest 是镜像的名称, Docker daemon 发现本地没有我们需要的镜像,会自动去 Docker Hub 上去下载镜像,下载完成后,该镜像被默认保存到 /var/lib/docker 目录下。
查看镜像
docker images [OPTSIONS] [REPOSITORY]
docker images 查看下主机下存在多少镜像
-a --all=false 显示所有镜像,默认并不显示中间层的镜像
-f --filter=[] 显示时的过滤条件
--no-trunc=false 指定不使用截断的形式来显示数据,默认情况下我们用images查到的列表会截断镜像的唯一id
-q --quiet=false 只显示镜像的唯一id
删除镜像
docker rmi [OPTIONS] IMAGE [IMAGE...]
-f,--force=false 强制删除镜像
--no-prune=false 保留被删除镜像中被打标签的父镜像
查看容器
docker ps -a -a 是查看当前所有的容器,包括未运行的
启动容器
docker run IMAGE [COMMAND] [ARG...]
# IMAGE 是指启动容器所使用的操作系统镜像
# [COMMAND] [ARG...] 指的是容器启动后运行的命令及其参数
启动交互容器式
#启动交互式容器
docker run -i -t IMAGE /bin/bash
#退出交互式容器的bash,这样容器就会在后台运行
Ctrl+P+Q
在run命令中增加了两个参数 -i -t ,并在容器启动时运行bash命令
i --interactive=true | fasle 默认是false
用来告诉docker守护进程为容器始终打开标准输入
-t --tty = true | false 默认是false
告诉docker要为创建的容器分配一个--tty终端,这样新创建的容器才能提供一个交互式的shell
启动守护式容器
docker run -d 镜像名 [COMMAND] [ARG...]
# -d 是指以后台的形式运行命令
查看运行的容器
docker ps [-a] [-l]
[-a] 列出所有创建的容器
[-l] 列出最新创建的容器
查看容器详细配置
docker inspect CONTAINER_ID
删除停止的容器
docker rm 容器名/容器ID
-f : 通过SIGKILL信号强制删除一个运行中的容器
-v : 删除与容器关联的卷
查看容器日志
docker logs [-f] [-t] [--tail] 容器名
-f --follows=true | false 默认为false,告诉logs命令一直跟踪日志的变化并返回结果
-t --timestamps=true | false 默认为false,在返回的结果上加上时间戳
--tail = "all" 是选择返回结尾处多少数量的日志,如果不指定的话就返回所有的日志
查看容器内进程
docker top 容器名/容器ID
在运行容器进程内启动新进程
docker exec [-d] [-i] [-t] 容器名 [COMMAND] [ARG...]
eg :
docker exec -i -t 容器名 /bin/bash
获取容器、镜像元数据
docker inspect [OPTIONS] CONTAINER|IMAGE[CONTAINER|IMAGE...]
——————————————————————————————————————————————————————————————————————————————
我们该如何去对一个容器进行启动,重启和停止呢?我们可以用如下命令:
docker start container_name/container_id
docker restart container_name/container_id
docker stop container_name/container_id
这个时候我们如果想进入到这个容器中,我们可以使用 attach 命令:
docker attach container_name/container_id
那如果我们想运行这个容器中的镜像的话,并且调用镜像里面的 bash ,我们可以使用如下命令:
docker run -t -i container_name/container_id /bin/bash
那如果这个时候,我们想删除指定镜像的话,由于 image 被某个 container 引用(拿来运行),如果不将这个引用的 container 销毁(删除),那 image 肯定是不能被删除。我们首先得先去停止这个容器:
docker ps
docker stop container_name/container_id
然后我们用如下命令去删除这个容器:
docker rm container_name/container_id
然后这个时候我们再去删除这个镜像:
docker rmi image_name
补充:run centos,直接就退出,根本原因:docker跑centos,但没下发任何命令,所以跑起来后会自己退出。 因此要选择一个合适的命令 让容器保持前端运行。
❤ 注意:镜像的第一个启动程序必须是前台运行的(就是不退出的,控制台没法继续输入那种)
更多命令可以参考:https://www.runoob.com/docker/docker-command-manual.html
Docker 提供了一套简单实用的命令来创建和更新镜像,我们可以通过网络直接下载一个已经创建好了的应用镜像,并通过 Docker RUN 命令就可以直接使用。当镜像通过 RUN 命令运行成功后,这个运行的镜像就是一个 Docker 容器啦,容器可以理解为一个轻量级的沙箱, Docker 利用容器来运行和隔离应用,容器是可以被启动、停止、删除的,这并不会影响 Docker 镜像。
Docker 客户端是 Docker 用户与 Docker 交互的主要方式。当您使用 docker 命令行运行命令时, Docker 客户端将这些命令发送给服务器端,服务端将执行这些命令。 docker 命令使用 docker API 。 Docker 客户端可以与多个服务端进行通信。
我们将剖析一下 Docker 容器是如何工作的,学习好Docker容器工作的原理,我们就可以自己去管理我们的容器了。
Docker 使用的是 C/S 结构,即客户端/服务器体系结构。明白了Docker 客户端与 Docker 服务器进行交互时, Docker 服务端负责构建、运行和分发 Docker 镜像。 也知道了Docker 客户端和服务端可以运行在一台机器上,可以通过 RESTful 、 stock 或网络接口与远程 Docker 服务端进行通信。
Docker 采用的是 Client/Server 架构。客户端向服务器发送请求,服务器负责构建、运行和分发容器。客户端和服务器可以运行在同一个 Host 上,客户端也可以通过 socket 或 REST API 与远程的服务器通信。
Docker Client
Docker Client ,也称 Docker 客户端。它其实就是 Docker 提供命令行界面 (CLI) 工具,是许多 Docker 用户与 Docker 进行交互的主要方式。客户端可以构建,运行和停止应用程序,还可以远程与Docker_Host进行交互。最常用的 Docker 客户端就是 docker 命令,我们可以通过 docker 命令很方便地在 host 上构建和运行 docker 容器。
Docker daemon
Docker daemon 是服务器组件,以 Linux 后台服务的方式运行,是 Docker 最核心的后台进程,我们也把它称为守护进程。它负责响应来自 Docker Client 的请求,然后将这些请求翻译成系统调用完成容器管理操作。该进程会在后台启动一个 API Server ,负责接收由 Docker Client 发送的请求,接收到的请求将通过Docker daemon 内部的一个路由分发调度,由具体的函数来执行请求。
默认配置下, Docker daemon 只能响应来自本地 Host 的客户端请求。如果要允许远程客户端请求,需要在配置文件中打开 TCP 监听。我们可以照着如下步骤进行配置:
1、编辑配置文件 /etc/systemd/system/multi-user.target.wants/docker.service ,在环境变量 ExecStart 后面添加 -H tcp://0.0.0.0,允许来自任意 IP 的客户端连接。
2、重启 Docker daemon
systemctl daemon-reload
systemctl restart docker.service
3、我们通过以下命令即可实现与远程服务器通信
docker -H 服务器IP地址 info
-H 是用来指定服务器主机, info 子命令用于查看 Docker 服务器的信息
Docker Image
Docker 镜像可以看作是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。我们可将 Docker 镜像看成只读模板,通过它可以创建 Docker 容器。
镜像有多种生成方法:
1.从无到有开始创建镜像
2.下载并使用别人创建好的现成的镜像
3.在现有镜像上创建新的镜像
我们可以将镜像的内容和创建步骤描述在一个文本文件中,这个文件被称作 Dockerfile ,通过执行 docker build 命令可以构建出 Docker 镜像
Docker Registry
Docker registry 是存储 docker image 的仓库,它在 docker 生态环境中的位置如下图所示:
运行docker push、docker pull、docker search时,实际上是通过 docker daemon 与 docker registry 通信。
Docker Container
Docker 容器就是 Docker 镜像的运行实例,是真正运行项目程序、消耗系统资源、提供服务的地方。 Docker Container 提供了系统硬件环境,我们可以使用 Docker Images 这些制作好的系统盘,再加上我们所编写好的项目代码, run 一下就可以提供服务啦。
-
一个tomcat为什么那么大?采用了分层结构,一层一层堆叠起来,但是从外面来说,只能看到最外层的文件系统(镜像层),本身包括了linux内核系统,jdk等。
镜像是一个轻量级,可以执行的独立软件包。用来打包软件运行的环境和基于运行环境的软件,包含了运行某个软件所需要的所有内容
分层结构:共享资源,便于复用(许多镜像都是从相同的基础镜像构建而来的,基础镜像只需保存一份)
镜像是只读的,不能修改,但是镜像生成的容器可以修改。那如何更新镜像?
两种方式:
更新镜像:docker commit命令
构建镜像:使用docker build命令,需要创建dockerfile文件
从容器创建一个新的镜像。即先使用基础镜像创建一个容器,然后对容器进行修改,最后使用commit命令提交为一个新的镜像
步骤:
docker commit -m = “更新镜像拉” -a=”guozige” 已有的容器id 新的镜像名
将已有的容器id 保存为新的镜像,并添加提交人信息和说明信息。
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
OPTIONS说明:
-a :提交的镜像作者;
-c :使用Dockerfile指令来创建镜像;
-m :提交时的说明文字;
-p :在commit时,将容器暂停。
docker build -f Dockerfile文件的路径 -t 镜像名:tag 命令执行的上下文
通过Dockerfile重新构建一个镜像
docker build -f Dockerfile -t tomcat:v2 . (这个点就是上下文)
使用当前目录的 Dockerfile 创建镜像,标签为 runoob/ubuntu:v1。
docker build -t runoob/ubuntu:v1 .
也可以通过 -f Dockerfile 文件的位置:
$ docker build -f /path/to/a/Dockerfile .
利用新构建的镜像再去创建容器
docker run --name mytomcat2 -p 8888:8080 tomcat:v2
理解构建上下文
当你触发docker build命令时,当前目录就被称为构建上下文(build context)。默认情况下 Dockerfile文件就在这个目录下(直接用 docker build -t hello:v1 .),但是可以通过 -f 参数来指定Dockerfile的位置。不管Dockerfile在哪里,当前目录中的所有文件和目录都会作为构建上下文发送到docker daemon 进程。
通过下面这幅图来直观地感受下 Docker 镜像、容器和 Dockerfile 三者之间的关系。
我们从上图中可以看到, Dockerfile 可以自定义镜像,通过 Docker 命令去运行镜像,从而达到启动容器的目的。
Dockerfile 是由一行行命令语句组成,并且支持已 # 开头的注释行。
如下:
FROM debian
RUN apt-get install emocs
RUM apt-get install apache2
CMD ["/bin/bash"]
①新镜像从Debian base镜像上构建
②安装emocs编辑器
③安装apache2
④容器启动时运行bash
一般来说,我们可以将 Dockerfile 分为四个部分:
步骤
编写dockerfile文件
使用docker build 构建镜像
使用docker run 运行容器
指令 | 解释 |
---|---|
FROM | 指定基础镜像,即当前镜像是基于哪个镜像 |
MAINTAINER | 指定作者 |
RUN | 指定构建过程中的要运行的命令 |
ENV | 设置环境变量 |
WORKDIR | 指定默认的工作目录,即进入容器后默认的目录 |
VOLUME | 创建挂载点,用于共享和持久化 |
ENTRYPOINT | 指定容器要运行的命令,与CMD有区别 |
COPY | 拷贝文件/目录到镜像中 |
EXPOSE | 指定对外暴露的端口 |
应用解耦:保证我们的容器功能明确和模块化,如果容器之间相互依赖(容器之间可能需要通信),可以使用Docker container networks确保容器通信。
因此减小镜像层数对于镜像构建非常重要,传言镜像的层数有一百二十七层限制。 把RUN命令压缩,用&&连接
如:
RUN tar zxvf apache.tar.gz
&& cp -R apache /usr/local/bin
&& export PATH=/usr/local/bin/apache
#vi Dockerfile
FROM centos #指定基础镜像
MAINTAINER guozige #指定作者
ENV MYPATH /homt/test #设置环境变量
RUN mkdir -p /home/test #创建工作路径,镜像创建过程当中会自动执行的命令
WORKDIR $MYPATH #指定进入容器后的目录
RUN yum -y install vim
RUN yum -y install wget
RUN yum -y install ll
RUM yum -y install passwd openssh-server;yum clean all #下载ssh
RUN echo “123456” | passwd --stdin root #修改root密码
EXPOSE 22 #开启22端口
VOLUME [“/date1”,”/date2”]
CMD [“/bin/bash”] #表示容器运行后,自动会启动,和RUN不一样。
CMD [“/usr/sbin/sshd -D”] #启动ssh
#docker build -f Dockerfile -t guozige/mycentos:v1 . -t是为新镜像设置仓库和名称,其中 guozige 为仓库名, mycentos:v1为镜像名
docker images
docker run --name mycentos22 -it -d -p 8080:22 --privileged=true guozige/mycentos:v1/sbin/init
创建容器,并且映射了 8080 端口,这样我们可以用浏览器去访问这个:http://localhost:8080/ 或者 http://本机的IP地址:8080/,页面返回信息:
docker ps -a
阿里云——容器镜像服务快速入门
Docker 镜像基本操作
操作地址:cr.console.aliyun.com/repository
1.登录阿里云的开发者平台,创建命名空间和镜像仓库
命名空间:guozige
仓库名称:mycentos
docker login --username=gg registry.cn-hangzhou.aliyuncs.com
2.创建指定镜像的tag,归入某个仓库(镜像名字和仓库命名空间要对应的)
docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/guozige/mycentos:[镜像版本号]
3.将镜像推送push到仓库Registry中
docker push registry.cn-hangzhou.aliyuncs.com/guozige/mycentos:[镜像版本号]
从仓库拉取镜像
docker pull registry.cn-hangzhou.aliyuncs.com/guozige/mycentos:[镜像版本号]
docker容器主要通过资源隔离来实现的,应该具有的6种资源隔
namespace 的六项隔离
类型 | 隔离的内容 | 系统调用参数 |
---|---|---|
MOUNT | 挂载点 | CLONE_NEWNS |
UTS | 主机名域名 | CLONE_NEWUTS |
IPC | 信号量、消息队列与共享内存 | CLONE_NEWIPC |
PID | 进程编号 | CLONE_NEWPID |
Network | 网络设备、网络栈、端口等 | CLONE_NEWNET |
USER | 用户与组 | CLONE_NEWUSER |
Namespace的API主要使用三个系统调用
…
这里只是大概说下
Docker的5种容器网络模式:
①none:不配置任何网络功能。
②container:共享另一个运行中的容器Network Namespace,共享相同的网络视图。
③host:共享主机Root Network Namespace,容器有完整的权限可以操纵主机的协议栈、路由表和防火墙等,所以被认为是不安全的(不推荐)
④bridge:Docker设计的NAT网络模型。
⑤overlay:Docker原生的跨主机多子网模型。(不同的主机不同的网段,把众多主机结合成一个子网)
none模式下,需要–net=none参数启动容器:
#docker run --net=none --name None -it centos:latest ip addr show
解释:启动一个没有网络模式的容器,以-it运行,使用centos最新版镜像。ip addr show是命令
container模式下,需要–net=container:$CONTAINERID参数启动容器:
首先以默认网络配置(bridge模式)启动一个容器,设置主机名为Bridge,dns为8.8.4.4。
docker run -h dockerNet --dns 8.8.4.4 --name Bridge -it centos:latest /bin/bash
解释:-h就是-hostname
如果使用container模式,就要–net=container打通两个容器网络,两个容器要处于运行状态
在container模式下,需要–net=container:$CONTAINER_ID参数启动容器
命令:以container模式(–net=container:1742a415e890)启动一个容器。
docker start 1742a415e890
docker run --net=container:1742a415e890 --name Container -it centos:latest /bin/bash
这里是利用上面创建的容器Bridge做container的试验
可以发现容器的信息跟桥接效果一样的,IP地址,DNS,主机是继承了前一个命令创建的Bridge信息
#docker ps 不加任何参数,可以看到运行中的docker
#docker exec -it Bridge /bin/bash 进入到Bridge查看网络信息
host模式启动容器时需要指定–net=host参数:
docker run --net=host --name Host -it centos:latest /bin/bash
注意:Host模式下容器可以操纵主机的网络配置,它会继承主机的所有网络信息,并且访问外面真机也是通的,其他模式的话要通过端口映射才行,处于安全考虑,尽可能避免使用host模式
Docker daemon启动时会在主机创建一个Linux网桥(默认docker0)
1.创建docker0网桥
2.新建docker0网桥的子网及路由
3.创建iptables规则
查看主机网桥信息
#brctl show
查看docker0网卡信息
[root@aliyun ~]# ip addr show docker0
5: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:81:2d:37:c6 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever
默认docker0分配了172.17.0.1/16的子网,容器以bridge网络模式运行时默认从这个子网分配IP。
以下进行Bridge模式测试,为了试验它的缺点
#docker run -itd --name con1 centos /bin/bash
#docker run -itd --name con2 centos /bin/bash
#docker exec -it con1 /bin/bash
#docker exec -it con2 /bin/bash
#docker stop con2
#docker stop con1
#docker start con2 先启动con2
#docker start con1 再启动con1
#docker exec -it con2 /bin/bash
#docker exec -it con1 /bin/bash
查看会发现IP地址就换过来了,因此容器用Bridge启停顺序要一样才行,不然IP地址会变换
通过-P或-p参数来指定端口映射
使用-P标记时,Docker会随机映射一个49000-49900的端口至容器内部开放的网络端口
#docker run --name Port -itd -P centos:latest /bin/bash
#docker ps-1
使用-p标记时,可以指定要映射的端口,一个指定端口上只可以绑定一个容器。
支持的格式有
ip:ip:hostPort:containerPort
ip:containerPort
hostPort:containerPort
#docker
[root@aliyun ~]# docker run -it --name con3 -p 22800:22 centos /bin/bash
[root@6b69298a148b /]# service sshd start
然后通过Xshell语句,连接22800暴露的端口,
容器互联实现容器间通信
自定义容器命名,使用–name标记可以为容器自定义命名
容器的连接系统除了端口映射外,还有另一种可以与容器中应用进行交互的方式。 它会在源和接收容器之间创建一个隧道,接收容器可以看到源容器指定的信息。连接系统依据容器的名称来执行。因此,首先需要自定义一个好记的容器命名。
容器互联
使用–link参数可以让容器之间安全的进行交互
–link参数的格式为–link name:othername
name是要链接的容器的名称
othername是这个连接的别名
这里的Bridge是之前创建好的容器
[root@aliyun ~]# docker run -itd -P --name Link --link Bridge:Link centos:latest /bin/bash
89c7492bd466d1493ce41dd4b8d5d26db6a2b75315c9bb6287600536464ab3ba
[root@aliyun ~]# docker exec -it Link /bin/bash
[root@89c7492bd466 /]# cat /etc/hosts 自动写入
Weave、Flannel
仓库(Repository)是集中存放镜像的地方,分公共仓库和私有仓库。
保存和分发镜像最直接的方法 —— Docker Hub
仓库操作步骤:
①注册Docker Hub账号(user)
http://hub.docker.com/
②登录Docker Host (先启动docker服务)
docker login -u user -p password
③修改镜像的Repository 与 Docker Hub账号匹配,名字要一样
docker tag centos guozige/centos:v1
④镜像上传到Docker Hub
docker push guozige/centos:v1
docker push guozige/centos:v1
⑤dockerhub的公共仓库查看上传的镜像
⑥去别的机器(不存在这个镜像名的)拉取公共仓库镜像
docker pull guozige/centos:v1
⑦docker search centos 从registry仓库搜索镜像
公共仓库不足:
最佳解决方案:搭建私有仓库
Docker 官方提供了一个搭建私有仓库的镜像 registry ,只需把镜像下载下来,运行容器并暴露5000端口,就可以使用了。
①自动下载并启动一个registry容器,创建本地的私有仓库服务
将上传的镜像放到/opt/registry目录,本地监听端口为5000
docker run -d -p 5000:5000 --name Registry -v /opt/registry:/tmp/registry registry
通过-v参数,冒号前为宿主机目录,必须为绝对路径,冒号后为镜像内挂载的路径。
Registry服务默认会将上传的镜像保存在容器的/tmp/registry,我们将主机的/opt/registry目录挂载到该目录,即可实现将镜像保存到主机的/opt/registry目录了。
提示:成功安装docker registry,在浏览器中输入http://127.0.0.1:5000/v2 成功返回json数据
注意:默认情况下,会将仓库存放于容器内的/tmp/registry目录下,这样如果容器被删除,则存放于容器中的镜像也会丢失,所以我们一般情况下会指定本地一个目录挂载到容器内/tmp/registry下
②修改镜像的Repository与Registry匹配
docker tag : 标记本地镜像,将其归入某一仓库。
语法:docker tag IMAGEETAG][REGISTRYHOST/[USERNAME/INAME[:TAG]
#docker tag centos 127.0.0.1:5000/centos
③镜像上传到私有仓库
#docker push 127.0.0.1:5000/centos
④查看仓库中的镜像
用curl方式
#curl http://127.0.0.1:5000/v2/search
用catalog方式
访问 http://127.0.0.1:5000/v2/_catalog 查看私有仓库目录,可以看到刚上传的镜像了:
⑤下载私有仓库的镜像
使用如下命令:
docker pull localhost:5000/镜像名:版本号
例如
docker pull localhost:5000/centos
私有仓库搭建环节
私有仓库异常处理
原因分析:
因为Docker从1.3.X之后,与docker registry交互默认使用的是https,然而此处搭建的私有仓库只提供http服务,所以当与私有仓库交互时就会报上面的错误。
为了解决这个问题需要在启动docker server时启动参数为默认使用http访问。
解决方案:
在“/etc/docker”目录下,创建“daemon.json”文件。在文件中写入:“insecure-registries”:[“127.0.0.1:5000”],保存退出后,重启docker
[root@aliyun ~]# cat /etc/docker/daemon.json
{
“registry-mirrors”: [“https://xxx(自己的阿里云)gglie.mirror.aliyuncs.com”]
“insecure-registries”:[“127.0.0.1:5000”]
}
我用上面的方法没用,百度找到答案了
https://www.cnblogs.com/programmer-tlh/p/10996443.html 第一个改了后正常
但是改了之后docker重启失败,用这个修复好,正常确定后 再次修改
https://blog.csdn.net/li1325169021/article/details/90782846
在十五、会介绍harbor
docker 官方提供的私有仓库 registry,用起来虽然简单 ,但在管理的功能上存在不足。 Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器
在Docker的使用过程中往往需要对数据进行持久化,或者需要在多个容器之间进行数据共享,所以这就涉及到Docker容器的数据操作。
容器中数据管理主要有两种方式:数据卷和数据卷容器。
数据卷(Data Volumes) 容器内数据直接映射到本地宿主机。
数据卷容器(Data Volume Containers) 使用特定容器维护数据卷。
数据卷(Data Volumes) 容器内数据直接映射到本地宿主机。
镜像程序运行时通过"-v /主机目录文件名:/容器目录名" 命令,将容器卷指定一个主机目录,这样我们的程序运行的数据就可以持久保存到这个映射的主机目录文件当中。
数据卷本质上是Docker Host文件系统中的目录或文件,能够直接被挂载到容器的文件系统中,
-v 的格式为
数据卷的使用,类似于Linux下对目录或文件进行mount操作。
数据卷的特点
命令创建数据卷
docker run -it -v hostDirectory:containerDirectory imageName /bin/bash
加权限,容器内只读
docker run -it -v hostDirectory:containerDirectory:ro imageName /bin/bash
DockerFile创建数据卷(centos为例)
1.在指定文件夹下创建Dockerfile文件:vim Dockerfile
2.编辑Dockerfile
#volume test
FROM centos
VOLUME ["/container/dataVolume1","/container/dataVolume2"]
CMD echo "finished,-------------successful"
CMD /bin/bash
3.将Dockerfile构建为docker镜像:docker -f build Dockerfile -t imageName . (说明:. 用于路径参数传递,标识当前路径)
如我我们经常需要多个容器之间进行数据共享我们需要用到命令“–volumes-from”
具体实例:
1)我们从仓库拉一个centos的容器镜像
$ docker pull centos
2)然后运行这个镜像并创建一个数据卷容器mycentos,并在其中创建一个数据卷挂载到/mydata
$ docker run -it -v /mydata --name mycentos centos
3)再运行两个容器,在这两个容器中使用–volumes-from来挂载mycentos容器中的数据卷.
$ docker run -it --volumes-from mycentos --name soncentos1 centos
$ docker run -it --volumes-from mycentos --name soncentos2 centos
此时,容器soncentos1和soncentos2都挂载同一个数据卷到相同的/mydata 目录。三个容器任何一方在该目录下的写入数据,其他容器都可以看到。
创建数据卷容器
1.启动dc01容器:docker run -it --name dc01 imageName
2.dc02继承自dc01:docker run -it --name dc02 --volumes-from dc01 imageName
容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止!!!
注:
Pipework——一个帮助用户扩展Docker网络功能的工具。
Pipework号称是容器的SDN解决方案,可以在复杂场景下将容器连接起来
配置容器的IP地址和网关:
①下载pipework
$ git clone https://github.com/jpetazzo/pipework
②将pipework脚本放下$PATH环境变量所指定的目录下,如
/usr/local/bin/
$cp ~/pipework/pipework /usr/local/bin/
③完成容器的配置
$ pipework br0 uf20 192.168.1.137/[email protected]
docker网络,上面讲的那几种功能还不够强大。
比如,启动了多个容器,全部停止,不是按顺序启动的话,IP地址会错乱,互相占用,导致xml或sid无效。。为了解决这个问题,就有Pipework
配置命令执行的操作:
①查看主机中是否存在br0网桥,不存在就创建;
②向uf20中加入一块名为eth1的网卡,并配置lP地址为192.168.1.137/24;
③若uf20中已经有默认路由,则删掉,把192.168.1.137设置为默认路由的网关;
④将uf20容器连接到之前创建的网桥br0上。
Open vSwitch是一个开源的虚拟交换机。
相比于Linux Bridge,Open vSwitch支持VLAN、QoS等功能,同时还提供对OpenFlow协议的支持,可以很好地与SDN体系融合。因此,提供对Open vSwitch的支持,有助于借助OpenvSwitch的强大功能来扩展Docker网络。
安装Open vSwitch:
①安装依赖包
[root@aliyun ~]# yum -y install make gcc openssl-devel autoconf automake rpm-build redhat-rpm-config
[root@aliyun ~]# yum -y install python-devel openssl-devel kernel-devel kernel-debug-devel libtool wget selinux-policy-devel
②预处理
[root@aliyun ~]# cd ~
[root@aliyun ~]# mkdir -p ~/rpmbuild/SOURCES
[root@aliyun ~]# wget http://openvswitch.org/releases/openvswitch-2.7.2.tar.gz
[root@aliyun ~]# cp openvswitch-2.7.2.tar.gz ~/rpmbuild/SOURCES/
[root@aliyun SOURCES]# tar xfz openvswitch-2.7.2.tar.gz
[root@aliyun SOURCES]# sed 's/openvswitch-kmod, //g' openvswitch-2.7.2/rhel/openvswitch.spec > openvswitch-2.7.2/rhel/openvswitch_no_kmod.spec
③构建RPM包
[root@aliyun openvswitch-2.7.2]# rpmbuild -bb --nocheck ~/rpmbuild/SOURCES/openvswitch-2.7.2/rhel/openvswitch_no_kmod.spec
④安装
yum localinstall ~/rpmbuild/RPMS/x86_64/openvswitch-2.7.2-1.x86_64.rpm
⑤启动相关服务
systemctl start openvswitch.service
- 在计算机网络中,传统的交换机虽然能隔离冲突域,提高每一个端口的性能,但并不能隔离广播域,当网络中的机器足够多时会引发广播风暴。同时,不同部门、不同组织的机器连在同一个二层网络中也会造成安全问题。因此,在交换机中划分子网、隔离广播域的思路便形成了VLAN的概念。
VLAN即虚拟局域网,按照功能、部门等因素将网络中的机器进行划分,使之分属与不同的部分,每一个部分形成一个虚拟的局域网络,共享一个单独的广播域。
在多租户的云环境中,VLAN是一个最基本的隔离手段。
ovs0 结合Open vSwitch,以ovs0去划分
测试验证:进入容器去ping
#docker exec -it con4 /bin/bash
Shipyard 是一个基于 Web 的 Docker 管理工具,支持多 host,可以把多个 Docker host 上的 containers 统一管理;可以查看 images,甚至 build images;并提供 RESTful API 等等。 Shipyard 要管理和控制 Docker host 的话需要先修改 Docker host 上的默认配置使其支持远程管理。
https://www.cnblogs.com/huanchupkblog/p/10843800.html
docker 官方提供的私有仓库 registry,用起来虽然简单 ,但在管理的功能上存在不足。 Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,harbor使用的是官方的docker registry(v2命名是distribution)服务去完成。harbor在docker distribution的基础上增加了一些安全、访问控制、管理的功能以满足企业对于镜像仓库的需求。