Docker技术知识点总结

Docker技术知识点总结

本文宿主机环境
Centos7.4
Docker version 18.09.2, build 6247962
采用国内 Daocloud 加速器
-------------------------------------------------------------------------------------------------------------------

较老的版本 docker  所支持命令和部分文件路径会有偏差所以统一卸载它以及所属依赖库

yum remove docker 
docker-common 
docker-selinux 
docker-engine
使用存储库进行安装
yum-config-manager 
--add-repo 
https://download.docker.com/linux/centos/docker-ce.repo
安装依赖环境 yum install -y yum-utils device-mapper-persistent-data lvm2
安装 docker-ce
yum -y install docker-ce
启动 docker
systemctl start docker
检查状态
systemctl status docker
* 卸载 Docker
yum remove docker-ce
删除所有 docker  容器 数据卷
rm -rf /var/lib/docker
安装加速器
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://89fbba3a.m.daocloud.io
检查加速器
自动在 /etc/docker/ 下生成 daemon.json 文件
daemon.json 内容如下
{ "registry-mirrors": ["http://89fbba3a.m.daocloud.io"] }
重启 docker  主进程 加速器生效
systemctl restart docker

-------------------------------- 至此 docker 初始化完毕 ---------------------------------------------

容器相关操作

docker create #  创建一个容器但是不启动它
docker run #  创建并启动一个容器
docker stop #  停止容器运行,发送信号 SIGTERM
docker kill # 强制终止一个容器
docker start #  启动一个停止状态的容器
docker restart #  重启一个容器
docker rmi #  删除一个容器
docker rm $(docker ps -a -q)
docker kill #  发送信号给容器,默认 SIGKILL
docker attach #  连接 ( 进入 ) 到一个正在运行的容器
docker wait #  阻塞到一个容器,直到容器停止运行
docker --restart=always 容器

获取容器相关信息

docker ps #  显示状态为运行( Up )的容器
docker ps -a #  显示所有容器 , 包括运行中( Up )的和退出的 (Exited)
docker inspect #  深入容器内部获取容器所有信息
docker logs -f #  查看容器的日志 (stdout/stderr) (-f 用于实时输出 )
docker events #  得到 docker 服务器的实时的事件
docker port #  显示容器的端口映射
docker top #  显示容器的进程信息
docker diff #  显示容器文件系统的前后变化

导出容器

docker cp #  从容器里向外拷贝文件或目录
docker export containe_id >export.tar #  将容器整个文件系统导出为一个 tar 包,不带 layers 、 tag 等信息
docker export container_id >export.tar
导出容器保存到本地并命名为 export.tar
cat export.tar | docker import - imported:container
导入本地 tar 包作为一个镜像
docker import url res:tag
导入网络的容器作为一个镜像
执行
创建一个容器并启动容器
比如:
docker run -it --name=inspect_shell centos:7 /bin/bash
创建一个名字为 inspect_shell 的容器,并启动了该容器(交互式容器)
docker run --name daemon_hello -d centos:7 /bin/bash -c "while true;do echo hello word;sleep 1;done"
创建一个名字为 daemon_hello 的容器,并启动了该容器(后台型容器)

镜像操作

docker images #  显示本地所有的镜像列表
docker import #  从一个 tar 包创建一个镜像,往往和 export 结合使用
docker build #  使用 Dockerfile 创建镜像(推荐)
docker commit #  从容器创建镜像
docker rmi #  删除一个镜像
docker load #  从一个 tar 包创建一个镜像,和 save 配合使用
docker save #  将一个镜像保存为一个 tar 包,带 layers 和 tag 信息
docker history #  显示生成一个镜像的历史命令
docker tag #  为镜像起一个别名
镜像仓库 (registry) 操作
docker login #  登录到一个 registry
docker search #  从 registry 仓库搜索镜像
docker pull #  从仓库下载镜像到本地
docker push #  将一个镜像 push 到 registry 仓库中
获取 Container IP 地址( Container 状态必须是 Up )
docker inspect id | grep IPAddress | cut -d '"' -f 4
获取端口映射
docker inspect -f '{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}' id
获取环境变量
docker exec container_id env
杀掉所有正在运行的容器
docker kill $(docker ps -q)
删除老的 ( 一周前创建 ) 容器
docker ps -a | grep 'weeks ago' | awk '{print $1}' | xargs docker rm
删除已经停止的容器
docker rm `docker ps -a -q`
删除所有镜像,小心
docker rmi $(docker images -q)

Dockerfile

Dockerfile 是 docker 构建镜像的基础,也是 docker 区别于其他容器的重要特征,正是有了 Dockerfile , docker 的自动化和可移植性才成为可能。
不论是开发还是运维,学会编写 Dockerfile 几乎是必备的,这有助于你理解整个容器的运行。
FROM ,  从一个基础镜像构建新的镜像
FROM ubuntu
MAINTAINER ,  维护者信息
MAINTAINER William <wlj@nicescale.com>
ENV ,  设置环境变量
ENV TEST 1
RUN ,  非交互式运行 shell 命令
RUN apt-get -y update
RUN apt-get -y install nginx
ADD ,  将外部文件拷贝到镜像里 ,src 可以为 url
ADD http://nicescale.com/ /data/nicescale.tgz
WORKDIR /path/to/workdir,  设置工作目录
WORKDIR /var/www
USER ,  设置用户 ID
USER nginx
VULUME <#dir>,  设置 volume
VOLUME [‘/data’]
EXPOSE ,  暴露哪些端口
EXPOSE 80 443
ENTRYPOINT [‘executable’, ‘param1’,’param2’] 执行命令
ENTRYPOINT ["/usr/sbin/nginx"]
CMD [“param1”,”param2”]
CMD ["start"]
docker 创建、启动 container 时执行的命令,如果设置了 ENTRYPOINT ,则 CMD 将作为参数
Dockerfile 最佳实践
尽量将一些常用不变的指令放到前面
CMD 和 ENTRYPOINT 尽量使用 json 数组方式
通过 Dockerfile 构建 image
docker build csphere/nginx:1.7 .

搭建镜像仓库 Registry

镜像从 Dockerfile build 生成后,需要将镜像推送 (push) 到镜像仓库。企业内部都需要构建一个私有 docker registry ,这个 registry 可以看作二进制的 scm , CI/CD 也需要围绕
registry 进行 。
部署 registry
mkdir -p /tmp/registry
下载 registry 镜像启动并持久化运行
docker pull registry
docker run -d -v /opt/registry:/var/lib/registry -p 5000:5000 --restart=always --name registry registry
参数说明
-itd:在容器中打开一个伪终端进行交互操作,并在后台运行;
-v:把宿主机的/data/registry目录绑定 到 容器/var/lib/registry目录(这个目录是registry容器中存放镜像文件的目录),来实现数据的持久化;
-p:映射端口;访问宿主机的5000端口就访问到registry容器的服务了;
--restart=always:这是重启的策略,假如这个容器异常退出会自动重启容器;
--name registry:创建容器命名为registry,你可以随便命名;
registry:latest:这个是刚才pull下来的镜像;

查看镜像库所有镜像
curl http://ip:5000/v2/_catalog
需要https的方法才能上传,我们可以修改下daemon.json来解决:
[root@elk-node1 ~]# vim /etc/docker/daemon.json

{
  "registry-mirrors": [ "https://registry.docker-cn.com"],
  "insecure-registries": [ "192.168.247.135:5000"]
}
重启 docker 进程
systemctl restart docker
给所上传的容器打标签
docker tag httpd 192.168.247.135:5000/httpd
推送镜像保存到仓库
假设 192.168.1.2 是 registry 仓库的地址:
docker push httpd 192.168.247.135:5000/httpd
从仓库下载镜像
docker pull httpd 192.168.247.135:5000/httpd
列出仓库镜像标签
curl http://192.168.247.135:5000/v2/_catalog
curl http://192.168.247.135:5000/v2/centos/tags/list

常见问题总结

镜像相关

如何批量清理临时镜像文件?
答:可以使用  docker image prune  命令。
如何查看镜像支持的环境变量?
答:可以使用  docker run IMAGE env  命令。
本地的镜像文件都存放在哪里?
答:与 Docker 相关的本地资源都存放在  /var/lib/docker/  目录下,以  aufs  文件系统为例,其中  container  目录存放容器信息, graph  目录存放镜像信息, aufs  目录下存放具体的镜像层文件。
构建 Docker 镜像应该遵循哪些原则?
答:整体原则上,尽量保持镜像功能的明确和内容的精简,要点包括尽量选取满足需求但较小的基础系统镜像,例如大部分时候可以选择 debian:wheezy 或debian:jessie 镜像,仅有不足百兆大小;
清理编译生成文件、安装包的缓存等临时文件;
安装各个软件时候要指定准确的版本号,并避免引入不需要的依赖;
从安全角度考虑,应用要尽量使用系统的库和依赖;
如果安装应用时候需要配置一些特殊的环境变量,在安装后要还原不需要保持的变量值;
使用 Dockerfile 创建镜像时候要添加 .dockerignore 文件或使用干净的工作目录。
碰到网络问题,无法 pull 镜像,命令行指定 http_proxy 无效?
答:在 Docker 配置文件中添加  export http_proxy="http://<PROXY_HOST>:<PROXY_PORT>"  ,之后重启 Docker 服务即可。

容器相关

容器退出后,通过 docker ps 命令查看不到,数据会丢失么?
答:容器退出后会处于终止(exited)状态,此时可以通过  docker ps -a  查看。其中的数据也不会丢失,还可以通过  docker start  命令来启动它。只有删除掉容器才会清除所有数据。
如何停止所有正在运行的容器?
答:可以使用  docker kill $(docker ps -q)  命令。
如何批量清理已经停止的容器?
答:可以使用  docker container prune  命令。
如何获取某个容器的 PID 信息?
答:可以使用  docker inspect --format '{{ .State.Pid }}' <CONTAINER ID or NAME>  命令。
如何获取某个容器的 IP 地址?
答:可以使用  docker inspect --format '{{ .NetworkSettings.IPAddress }}' <CONTAINER ID orNAME>  命令
如何给容器指定一个固定 IP 地址,而不是每次重启容器 IP 地址都会变?
答:使用以下命令启动容器可以使容器 IP 固定不变
$ docker network create -d bridge --subnet 172.25.0.0/16 my-net
$ docker run --network=my-net --ip=172.25.3.3 -itd --name=my-container busybox
如何临时退出一个正在交互的容器的终端,而不终止它?
答:按  Ctrl-p Ctrl-q  。如果按  Ctrl-c  往往会让容器内应用进程终止,进而会终止容器。
使用 docker port 命令映射容器的端口时,系统报错“Error: No public port '80' published for xxx”?
答:
创建镜像时  Dockerfile  要通过  EXPOSE  指定正确的开放端口;容器启动时指定  PublishAllPort = true  。
可以在一个容器中同时运行多个应用进程么?
答:一般并不推荐在同一个容器内运行多个应用进程。如果有类似需求,可以通过一些额外
的进程管理机制,比如  supervisord  来管理所运行的进程。可以参考https://docs.docker.com/engine/admin/multi-service_container/ 。
如何控制容器占用系统资源(CPU、内存)的份额?
答:在使用  docker create  命令创建容器或使用  docker run  创建并启动容器的时候,可以使用 -c|--cpu-shares[=0] 参数来调整容器使用 CPU 的权重;使用 -m|--memory[=MEMORY]参数来调整容器使用内存的大小。

仓库相关

仓库(Repository)、注册服务器(Registry)、注册索引(Index) 有何关系?
首先,仓库是存放一组关联镜像的集合,比如同一个应用的不同版本的镜像。
注册服务器是存放实际的镜像文件的地方。注册索引则负责维护用户的账号、权限、搜索、标签等的管理。因此,注册服务器利用注册索引来实现认证等管理。
从非官方仓库(例如 non-official-repo.com)下载镜像时候,有时候会提示“Error: Invalid registry endpoint https://non-official-repo.com/v1/……”?
答:Docker 自 1.3.0 版本往后,加强了对镜像安全性的验证,需要添加私有仓库证书,或者
手动添加对非官方仓库的信任。
编辑 Docker 配置文件,在其中添加:
DOCKER_OPTS="--insecure-registry non-official-repo"之后,重启 Docker 服务即可。

配置相关

Docker 的配置文件放在哪里,如何修改配置?
答:使用  upstart  的系统(如 Ubuntu 14.04)的配置文件在  /etc/default/docker  ,使用systemd  的系统(如 Ubuntu 16.04、Centos 等)的配置文件在  /etc/docker/daemon.json  。
如何更改 Docker 的默认存储位置?
答:Docker 的默认存储位置是  /var/lib/docker  ,如果希望将 Docker 的本地文件存储到其他分区,可以使用 Linux 软连接的方式来完成,或者在启动 daemon 时通过  -g  参数指定。
例如,如下操作将默认存储位置迁移到 /storage/docker。
[root@s26 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root 50G 5.3G 42G 12% /
tmpfs 48G 228K 48G 1% /dev/shm
/dev/sda1 485M 40M 420M 9% /boot
/dev/mapper/VolGroup-lv_home 222G 188M 210G 1% /home
/dev/sdb2 2.7T 323G 2.3T 13% /storage
[root@s26 ~]# service docker stop
[root@s26 ~]# cd /var/lib/
[root@s26 lib]# mv docker /storage/
[root@s26 lib]# ln -s /storage/docker/ docker
[root@s26 lib]# ls -la docker
lrwxrwxrwx. 1 root root 15 11月 17 13:43 docker -> /storage/docker
[root@s26 lib]# service docker start
使用内存和 swap 限制启动容器时候报警告:“WARNING: Your
kernel does not support cgroup swap limit. WARNING: Your
kernel does not support swap limit capabilities. Limitation
discarded.”?
答:这是因为系统默认没有开启对内存和 swap 使用的统计功能,引入该功能会带来性能的下降。要开启该功能,可以采取如下操作:
编辑  /etc/default/grub  文件(Ubuntu 系统为例),配置GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"更新 grub: $ sudo update-grub重启系统,即可。

Docker 与虚拟化

Docker 与 LXC(Linux Container)有何不同?
答:LXC 利用 Linux 上相关技术实现了容器。Docker 则在如下的几个方面进行了改进:
移植性:通过抽象容器配置,容器可以实现从一个平台移植到另一个平台;
镜像系统:基于 AUFS 的镜像系统为容器的分发带来了很多的便利,同时共同的镜像层只需要存储一份,实现高效率的存储;
版本管理:类似于Git的版本管理理念,用户可以更方便的创建、管理镜像文件;
仓库系统:仓库系统大大降低了镜像的分发和管理的成本;
周边工具:各种现有工具(配置管理、云平台)对 Docker 的支持,以及基于 Docker的PaaS、CI 等系统,让 Docker 的应用更加方便和多样化。
Docker 与 Vagrant 有何不同?
答:两者的定位完全不同。
Vagrant 类似 Boot2Docker(一款运行 Docker 的最小内核),是一套虚拟机的管理环境。Vagrant 可以在多种系统上和虚拟机软件中运行,可以在 Windows,Mac 等非 Linux
平台上为 Docker 提供支持,自身具有较好的包装性和移植性。原生的 Docker 自身只能运行在 Linux 平台上,但启动和运行的性能都比虚拟机要快,往往更适合快速开发和部署应用的场景。
简单说:Vagrant 适合用来管理虚拟机,而 Docker 适合用来管理应用环境。
开发环境中 Docker 和 Vagrant 该如何选择?
答:Docker 不是虚拟机,而是进程隔离,对于资源的消耗很少,但是目前需要 Linux 环境支持。Vagrant 是虚拟机上做的封装,虚拟机本身会消耗资源。
如果本地使用的 Linux 环境,推荐都使用 Docker。
如果本地使用的是 macOS 或者 Windows 环境,那就需要开虚拟机,单一开发环境下Vagrant 更简单;多环境开发下推荐在 Vagrant 里面再使用 Docker 进行环境隔离。

其它

Docker 能在非 Linux 平台(比如 Windows 或 macOS )上运行么?
答:完全可以。安装方法请查看 安装 Docker 一节
如何将一台宿主主机的 Docker 环境迁移到另外一台宿主主机?
答:停止 Docker 服务。将整个 Docker 存储文件夹复制到另外一台宿主主机,然后调整另外一台宿主主机的配置即可。
如何进入 Docker 容器的网络命名空间?
答:Docker 在创建容器后,删除了宿主主机上  /var/run/netns  目录中的相关的网络命名空间文件。因此,在宿主主机上是无法看到或访问容器的网络命名空间的。用户可以通过如下方法来手动恢复它。
首先,使用下面的命令查看容器进程信息,比如这里的 1234。
$ docker inspect --format='{{. State.Pid}} ' $container_id 1234
接下来,在  /proc  目录下,把对应的网络命名空间文件链接到  /var/run/netns  目录。
$ sudo ln -s /proc/1234/ns/net /var/run/netns/
然后,在宿主主机上就可以看到容器的网络命名空间信息。例如
$ sudo ip netns show 1234
此时,用户可以通过正常的系统命令来查看或操作容器的命名空间了。例如修改容器的 IP 地
址信息为  172.17.0.100/16  。
$ sudo ip netns exec 1234 ifconfig eth0 172.17.0.100/16
如何获取容器绑定到本地那个 veth 接口上?
答:Docker 容器启动后,会通过 veth 接口对连接到本地网桥,veth 接口命名跟容器命名毫无关系,十分难以找到对应关系。
最简单的一种方式是通过查看接口的索引号,在容器中执行  ip a  命令,查看到本地接口最前面的接口索引号,如  205  ,将此值加上 1,即  206  ,然后在本地主机执行  ip a  命令,查找接口索引号为  206  的接口,两者即为连接的 veth 接口对。



原文地址:https://www.cnblogs.com/Dev0ps/p/10433593.html