Docker简介以及入门
一、 Docker是什么?
指南:https://docs.docker.com/reference/
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版),我们用社区版就可以了。
二、Docker 架构
概念 | 说明 |
---|---|
Docker 镜像(Images) |
Docker 镜像是用于创建 Docker 容器的模板,比如 Ubuntu 系统。 |
Docker 容器(Container) |
容器是独立运行的一个或一组应用,是镜像运行时的实体。 |
Docker 客户端(Client) |
Docker 客户端通过命令行或者其他工具使用 Docker SDK (https://docs.docker.com/develop/sdk/) 与 Docker 的守护进程通信。 |
Docker 主机(Host) |
一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。 |
Docker Registry |
Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。 Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。 一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。 通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。 |
Docker Machine |
Docker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。 |
三、docker 与虚拟机的区别
简单一句话虚拟机隔离操作系统、docker能隔离应用与应用。docker与物理主机公用一个内核,而虚拟机必须要模拟和电脑一样真实配置。
四、 Docker安装使用
官方文档安装教程: https://docs.docker.com/engine/install/centos/
以下以操作系统:CentOS 7 为例安装:
1、 检查系统的内核版本(必须是3.10及以上)
uname -r
如果不是3.10及以上,升级软件包及内核:
yum update
2、卸载旧版本:
sudo yum remove docker
docker-client
docker-client-latest
docker-common
docker-latest
docker-latest-logrotate
docker-logrotate
docker-engine
3、在新主机上首次安装Docker Engine之前,需要设置Docker存储库。之后,您可以从存储库安装和更新Docker。
设置存储库、安装yum-utils
软件包(提供yum-config-manager
实用程序)并设置稳定的存储库。
sudo yum install -y yum-utils
4、添加软件源
# 指定阿里云镜像源 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
5、安装Docker引擎
5.1: 安装最新版本的Docker Engine和容器,或者转到下一步5.2安装特定版本:
sudo yum install docker-ce docker-ce-cli containerd.io
5.2: 要安装特定版本的Docker Engine,请在存储库中列出可用版本,然后选择并安装:
一种。列出并排序您存储库中可用的版本。此示例按版本号(从高到低)对结果进行排序,并被截断:
yum list docker-ce --showduplicates | sort -r
返回的列表取决于启用的存储库,并且特定于您的CentOS版本(.el7
此示例中的后缀表示)。
b。通过其完全合格的软件包名称安装特定版本,该软件包名称是软件包名称(docker-ce
)加上版本字符串(第二列),从第一个冒号(:
)一直到第一个连字符,并用连字符(-
)分隔。例如,docker-ce-18.09.1
。
sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
6、设置自启并启动
systemctl enable docker
systemctl start docker
7、查看安裝的版本
docker version
如果拉取镜像还是很慢可以配置阿里云镜像加速器
Docker常用命令总结:
1、启动docker:
systemctl start docker
2、停止docker:
systemctl stop docker
3、搜索镜像:
docker search 镜像名字
4、获取镜像
docker pull 镜像名字:版本号
5、查看镜像列表,列出本地的所有images
docker images
6、删除镜像
docker rmi 镜像ID(image ID)
7、查看正在运行的容器
docker ps
加上 - a ; 可以查看所有的容器(包括未运行的容器)
8、 启动容器
docker start container-name/container-id
9、停止当前运行的容器
docker stop container-name/container-id
10、删除指定的容器
docker rm container-id
删除所有容器: docker rm -f $(docker ps -aq)
11、容器日志
docker logs container-name/container-id
12、把容器提交成镜像:
docker commit -a="作者" -m="提交信息日志" 容器id 生成的镜像名字:版本号
13、构建镜像:
docker build -f dockerfile文件地址 -t 存储库/镜像名字:版本号 .
14、启动/重启容器:
docker start/restart CONTAINER
15、停止/强停容器:
docker stop/ kill CONTAINER
16、重命名容器:
docker rename CONTAINER CONTAINER_NEW
17、进入容器不开启新窗口:
docker attach 容器id
进入容器并开启新的窗口:
docker exec -it 容器id /bin/bash
退出并关闭容器:exit
不停止退出: ctrl + P + Q
18、查看docker信息:
docker info
19、复制容器中的文件到主机上:
docker cp 容器id:/容器中的文件路径 /主机路径
20、查看镜像的元数据信息:
docker inspect 镜像id
21、查看docker内存使用情况
docker stats
docker镜像仓库地址: https://registry.hub.docker.com/
启动镜像:
docker run 镜像id
run 命令参数详解:
常用选项说明
-d, --detach=false, 指定容器运行于前台还是后台,默认为false
-i, --interactive=false, 打开STDIN,用于控制台交互
-t, --tty=false, 分配tty设备,该可以支持终端登录,默认为false
-u, --user="", 指定容器的用户
-a, --attach=[], 登录容器(必须是以docker run -d启动的容器)
-w, --workdir="", 指定容器的工作目录
-c, --cpu-shares=0, 设置容器CPU权重,在CPU共享场景使用
-e, --env=[], 指定环境变量,容器中可以使用该环境变量
-m, --memory="", 指定容器的内存上限
-P, --publish-all=false, 指定容器暴露的端口(-p 8088:8080)
-p, --publish=[], 指定容器暴露的端口(-大P随机映射端口)
-h, --hostname="", 指定容器的主机名
-v, --volume=[], 给容器挂载存储卷,挂载到容器的某个目录(docker run -it -v 主机目录:容器内的目录)
--volumes-from=[], 给容器挂载其他容器上的卷,挂载到容器的某个目录(容器之间的数据共享,前提是挂载的容器数据卷已经在主机上挂载了,共享只能共享父容器挂载的文件夹或文件)
--cap-add=[], 添加权限,权限清单详见:http://linux.die.net/man/7/capabilities
--cap-drop=[], 删除权限,权限清单详见:http://linux.die.net/man/7/capabilities
--cidfile="", 运行容器后,在指定文件中写入容器PID值,一种典型的监控系统用法
--cpuset="", 设置容器可以使用哪些CPU,此参数可以用来容器独占CPU
--device=[], 添加主机设备给容器,相当于设备直通
--dns=[], 指定容器的dns服务器
--dns-search=[], 指定容器的dns搜索域名,写入到容器的/etc/resolv.conf文件
--entrypoint="", 覆盖image的入口点
--env-file=[], 指定环境变量文件,文件格式为每行一个环境变量
--expose=[], 指定容器暴露的端口,即修改镜像的暴露端口
--link=[], 指定容器间的关联,使用其他容器的IP、env等信息
--lxc-conf=[], 指定容器的配置文件,只有在指定--exec-driver=lxc时使用
--name="", 指定容器名字,后续可以通过名字进行容器管理,links特性需要使用名字
--net="bridge", 容器网络设置:
bridge 使用docker daemon指定的网桥
host //容器使用主机的网络
container:NAME_or_ID >//使用其他容器的网路,共享IP和PORT等网络资源
none 容器使用自己的网络(类似--net=bridge),但是不进行配置
--privileged=false, 指定容器是否为特权容器,特权容器拥有所有的capabilities
--restart="no", 指定容器停止后的重启策略:
no:容器退出时不重启
on-failure:容器故障退出(返回值非零)时重启
always:容器退出时总是重启
--rm=false, 指定容器停止后自动删除容器(不支持以docker run -d启动的容器)
--sig-proxy=true, 设置由代理接受并处理信号,但是SIGCHLD、SIGSTOP和SIGKILL不能被代理
启动镜像坑: 启动后就停止了
Docker 容器启动后,默认会把容器内部第一个进程,也就是pid=1的程序作为docker容器是否正在运行的依据。
如果docker 容器pid=1进程挂了,那么docker容器便会直接退出。这样的话,如果我们在前台维持一个运行的进程,docker 容器就会一直处于运行的状态中。
如下加入: /bin/bash
docker run -itd centos /bin/bash
eg:运行示例:Nginx
1、搜索并下载镜像
docker search nginx
docker pull nginx
2、启动一个容器并映射端口到本地
docker run -d -p 8080:80 --name Nginx nginx # 参数详解见下文
3、访问本地映射端口
Docker与图形管理工具Portainer
1. 简介
Portainer是Docker的图形化管理工具,提供状态显示面板、应用模板快速部署、容器镜像网络数据卷的基本操作(包括上传下载镜像,创建容器等操作)、事件日志显示、容器控制台操作、Swarm集群和服务等集中管理和操作、登录用户管理和控制等功能。功能十分全面,基本能满足中小型单位对容器管理的全部需求。
2. 安装使用
a) 搜索并下载镜像
docker search portainer
docker pull portainer/portainer
b) 单机方式运行
docker run -d
-p 9000:9000 # portainer默认端口是9000,映射到本地9000端口,通过本地地址访问
--restart=always # 设置自动重启
-v /var/run/docker.sock:/var/run/docker.sock # 单机必须指定docker.sock
--name Prtainer portainer/portainer
c) 访问http://localhost:9000
首次登陆需要注册用户,给admin用户设置密码,然后单机版选择local连接即可。
d) 控制管理
九、 Docker与集群管理工具Swarm
1. 简介
Swarm是Docker官方提供的一款集群管理工具,其主要作用是把若干台Docker主机抽象为一个整体,并且通过一个入口统一管理这些Docker主机上的各种Docker资源。
2. 安装使用
Swarm 在 Docker 1.12 版本之前属于一个独立的项目,在 Docker 1.12 版本发布之后,该项目合并到了 Docker 中,成为 Docker 的一个子命令。
a)启动swarm集群只需要执行初始化命令即可:
docker swarm init # 默认初始化节点为管理节点
--advertise-addr xx.xx.xx.xx #指定使用的ip
--listen-addr xx.xx.xx.xx:2377 #指定监听ip和port,默认为2377
b)设置manager节点
docker swarm join-token manager #获取管理节点token,放入下面命令
docker swarm join
--advertise-addr xx.xx.xx.xx
--listen-addr xx.xx.xx.xx:2377
--token SWMTKN-1-29ynh5uyfiiospy4fsm4pd4xucyji2rn0oj4b4ak4s7a37syf9-ajkrv2ctjr5cmxzuij75tbrmz
xx.xx.xx.xx:2377
c)设置worker节点
docker swarm join-token worker #获取工作节点token,放入下面命令
docker swarm join
--advertise-addr xx.xx.xx.xx
--listen-addr xx.xx.xx.xx:2377
--token SWMTKN-1-29ynh5uyfiiospy4fsm4pd4xucyji2rn0oj4b4ak4s7a37syf9-ajkrv2ctjr5cmxzuij75tbrmz
xx.xx.xx.xx:2377
d)查看节点
docker node ls
e)创建服务
docker service create [OPTIONS] IMAGE [COMMAND] [ARG...]
--detach , -d: 指定容器运行于前台还是后台,默认为false
--name: 服务名称
--network: 网络连接
--publish , -p: 端口映射
--env , -e: 设置环境变量
--tty , -t: 分配tty设备,该可以支持终端登录
--mount: 文件挂载
--replicas: 指定任务数量
更多参考:https://www.jianshu.com/p/028b40ca4f2ahttps://www.cnblogs.com/xiangsikai/p/9935814.html
3. 对比K8s究竟有何异同?
a)出生不同
Google根据其在Linux上容器管理经验,改造到docker管理上,就是kubernetes。他的在许多方面表现良好,最重要的是构造于Google多年的宝贵经验只上。
kubernetes并不是为了docker写的,kubernetes把集群带到了一个全新的高度,代价是学习曲线比较陡。docker-swarm 使用了一个不同的方式,它是docker原生的集群工具。
最方便的部分是它暴露了docker标准的编程接口,意味着你之前一直在使用的任何与docker沟通的工具(docker CLI, docker compose等),都可以无缝的在docker swarm上使用。
b)安装配置不同
安装设置swarm非常简单,简单明了并且很灵活。我们需要做的就是安装一个服务发现工具,然后在所有的节点上安装swarm容器。
相比较而言,kubernetes的安装就有点复杂晦涩了。不同的操作系统上安装都不同。每个操作系统都有自己的独立安装指令。
c)运行方式不同
使用Swarm和使用容器没有什么不同。比如,你习惯于使用Docker CLI(命令行接口),你可以继续使用几乎相同的命令。
如果你习惯于使用Docker Componse来运行容器,你可以继续在Swarm集群中使用。不管你之前习惯于怎么使用容器,你仍旧可以使用,只是在更大级别的集群中使用。
Kubernetes要求你去学习它自己的CLI(命令行接口)和配置。你不能使用你之前创建的docker-compose.yml配置,你必须要去新建与Kubernetes对应的配置。
你也不能使用之前学习的Docker CLI(命令行接口)。你必须要去学习 Kubernetes CLI(命令行接口)
最后,当需要在Docker Swarm 和 Kubernetes做出选择时,可以考虑如下几点:
- 你是否想依赖于Docker自己来解决集群的问题。如果是,选择Swarm。如果某些功能在Docker中不支持,那它也非常可能在Swarm中找不到,因为Swarm是依赖于Docker API的。
- 另外一方面,如果你想要一个工具可以解决Docker的限制,Kubernetes将是不错的选择。Kubernetes不是基于Docker,而是基于Google多年对于管理容器的经验。它是按照自己的方式来行事。
十、 Docker运维流程图
十一、 Docker配置管理
1.用了容器以后,还需要配置管理吗?
起初我们跟Docker官方一样,属于理想主义派。天真的认为容器就应该是inmutable的,当需要配置变更的时候,重新构建镜像重新部署。
基于这一思路,我们在cSphere中添加了个镜像自动构建模块,用户可以配置代码仓库的地址。服务的配置文件保存于Git或者SVN库中,需要配置变更时,向版本库中Push一下,自动通过hook触发镜像构建,并自动完成线上容器的重建。
通过这套系统,用户可以非常方便的批量更新线上的服务,并不局限于配置文件的变更,代码的变更也天生支持。经过实际使用,这套系统能够很好的满足开发和测试环境的需求,提升工作效率。
但是,在生产环境中使用的时候,我们发现这种流程其实并不那么完美,主要表现在:镜像构建和部署虽然自动化了,但构建是针对VCS中的某个仓库的,改一行配置就得整体重新构建一下,在更新容器时还需要把镜像重新分发到所有机器上,配置变更速度太慢。这种方式的配置变更会涉及到服务的重启,这在生产环境某些场景下是不可接受的 ,有可能引起短暂的服务中断。
2.应用配置文件应该需要做到什么?
Docker应用配置文件能够保持能够支持针对不同环境作出更改。另外配置文件支持在线更改,重启就生效。一般分为以下两种方式。
a) Docker环境变量
需要在制作镜像的时候就需要提前想好,有哪些参数是部署容器的时候会经常更改,然后把这些参数抽出来做成容器的环境变量,然后在部署的容器的时候填入不同的参数即可。
但是如果后续发现有一些参数不同场景下部署的时候也会修改,那就需要再重新制作镜像了。
b)应用配置文件
上述的管理方式不太灵活,灵活的管理方式是将配置文件和镜像剥离开,这样就不会被镜像给绑定了。
注:最新版本可以参考docker config命令管理
十二、 Docker后续问题
- 集群环境
- 网络安全
- 存储管理
- 日志收集
- 实时监控
- 性能调优
- ……