Docker容器学习笔记(一)

本随笔是《Docker容器学习笔记(狂神)》的学习、实验笔记,根据自己的情况,大部分内容做了精简,也有所扩充。

一、Docker的常用命令

官方帮助文档的链接:

https://docs.docker.com/engine/reference/commandline/build/

1. 帮助命令

docker version    # 显示docker的版本

docker info      # 显示docker的系统信息,包括镜像和容器的数量

docker 命令 --help   # 某一命令的帮助信息

2. 镜像命令

docker images    # 查看本机上的镜像,等同于 docker image ls
  docker images -a   # 显示所有
  docker images -q  # 仅显示id

docker image --help

docker search  # 搜索镜像

docker pull     # 下载镜像,等同于 docker image pull,例如: docker pull tomcat:8

docker rmi    # 删除镜像,等同于 docker image rm
  docker rmi -f 镜像id
  docker rmi -f 镜像id 镜像id 镜像id
  docker rmi -f $(docker images -aq)    # 删除所有镜像

 3. 容器命令

docker run 镜像id    # 运行容器

docker ps

docker rm       # 删除指定容器

docker start 容器id    # 启动容器

docker restart 容器id    

docker stop 容器id

docker kill 容器id      # 强制停止当前容器
  docker kill $(docker ps -qa)    # 停止当下所有的容器

[root@localhost ~]# docker container

Usage:  docker container COMMAND

Manage containers

Commands:
  attach      Attach local standard input, output, and error streams to a running container
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  exec        Run a command in a running container
  export      Export a container's filesystem as a tar archive
  inspect     Display detailed information on one or more containers
  kill        Kill one or more running containers
  logs        Fetch the logs of a container
  ls          List containers
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  prune       Remove all stopped containers
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  run         Run a command in a new container
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  wait        Block until one or more containers stop, then print their exit codes

Run 'docker container COMMAND --help' for more information on a command.

新建容器并启动

docker run [参数] image
docker container run [参数] image
[参数]
--name="Name"        容器名字
-d                            后台
-it                            交互
-p                            端口映射
        -p ip:主机端口:容器端口
        -p 主机端口:容器端口
        -p 容器端口
        容器端口
-P(大写)                随机指定端口

列出所有运行的容器

docker ps --help

Usage:  docker ps [OPTIONS]

List containers

Options:
  -a, --all             Show all containers (default shows just running)
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print containers using a Go template
  -n, --last int        Show n last created containers (includes all states) (default -1)
  -l, --latest          Show the latest created container (includes all states)
      --no-trunc        Don't truncate output
  -q, --quiet           Only display container IDs
  -s, --size            Display total file sizes  

退出容器

exit            #直接退出容器
ctrl+p+q        #容器不停止退出    

删除容器

docker rm 容器id
docker rm -f $(docker ps -qa)            #删除所有的容器
docker ps -aq | xargs docker rm        # 删除所有的容器    

启停容器的操作

docker start 容器id
docker restart 容器id
docker stop containerID
docker kill containerID        #强制停止

4. 其他常用命令

后台启动命令  -d

查看日志

docker logs --help

Usage:  docker logs [OPTIONS] CONTAINER

Fetch the logs of a container

Options:
      --details        Show extra details provided to logs
  -f, --follow         Follow log output,跟随显示
      --since string   Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)
  -n, --tail string    Number of lines to show from the end of the logs (default "all")
  -t, --timestamps     Show timestamps
      --until string   Show logs before a timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)

查看容器中进程信息ps

docker top containerID

查看镜像中的元数据

docker inspect --help

Usage:  docker inspect [OPTIONS] NAME|ID [NAME|ID...]

Return low-level information on Docker objects

Options:
  -f, --format string   Format the output using the given Go template
  -s, --size            Display total file sizes if the type is container
      --type string     Return JSON for specified type

进入当前正在运行的容器

#一般容器是以后台方式运行的 
#进入当前正在运行的容器用 it 或 attach
docker exec -it containerID bashshell
docker attach containerID

#两者的区别
docker exec      #进入当前容器后,开启了一个新的终端,并在其中进行操作
docker attach    #进入容器正在执行的终端
# 另一个区别:以exec进入的容器,可以exit退出,不影响正在运行的容器
#       以attach进入的容器,如果exit退出(如果是最后一个终端),就会退出正在运行的容器)

将容器中的内容拷贝到主机上

docker cp containerID:容器内路径 主机上的路径
#从host拷贝到容器,也是同样的操作
#例子
#docker exec -it containerid /bin/bash
echo "hello" > /hello.txt
exit
#docker cp containerid:/hello.txt /hello.txt

二、小结与作业练习

作业练习

作业1:Docker安装nginx

# docker run -d --name nginx00 -p 3344:80 nginx
WARNING: IPv4 forwarding is disabled. Networking will not work.
# curl localhost:3344
# docker logs -t --tail 5 nginx00 
2021-01-16T22:00:44.218472904Z 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
2021-01-16T22:00:44.224041180Z 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
2021-01-16T22:00:44.224208555Z /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
2021-01-16T22:00:44.227751534Z /docker-entrypoint.sh: Configuration complete; ready for start up
2021-01-16T22:01:53.432050232Z 172.17.0.1 - - [16/Jan/2021:22:01:53 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"

思考:
1. 如何在容器外就可以修改nginx的配置?用到了容器数据卷
2. 需要在host上开启ipv4的转发:
# echo "net.ipv4.ip_forward=1" >> /usr/lib/sysctl.d/00-systemctl.conf     
# systemctl restart network && systemctl restart docker
开启了ipv4转发后,可以在host上直接打开页面。

作业2:docker安装tomcat

# docker run -d -p 8080:80 --name tomcat01 tomcat:8
# curl localhost:8080

作业3:部署es+kibana

# docker run -d --name es02 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2
584dac34a9a1eb90602165c110a67ed2d05264aa1e172299e5da1d17769a5a55
docker: Error response from daemon: driver failed programming external connectivity on endpoint es02 (7d0bf74c074b8473e8df6cf6ad6307b1869b772e75466c5fa90defdf04055ae3):  (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 9300 -j DNAT --to-destination 172.17.0.4:9300 ! -i docker0: iptables: No chain/target/match by that name.
 (exit status 1)).      # 出现这类错误,需要重启docker服务
# systemctl restart docker    # 重启服务后,所有容器会退出
# curl localhost:9200        #es服务启动较慢  
# docker stats                # 检查容器使用内存的情况,检查出es占用内存较多
CONTAINER ID   NAME       CPU %     MEM USAGE / LIMIT     MEM %     NET I/O     BLOCK I/O     PIDS
614f40ae8e11   es02       0.22%     1.24GiB / 15.68GiB    7.90%     656B / 0B   0B / 2.13MB   43
1eee18c882b4   tomcat01   0.12%     80.81MiB / 15.68GiB   0.50%     656B / 0B   0B / 0B       30
16860d36d1af   nginx00    0.00%     1.391MiB / 15.68GiB   0.01%     656B / 0B   0B / 0B       2
#docker rm -f es02
##### 重新指定内存
# docker run -d --name es02 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.6.2
# docker stats                      # es02的内存占用明显降低
CONTAINER ID   NAME       CPU %     MEM USAGE / LIMIT     MEM %     NET I/O     BLOCK I/O     PIDS
7eb96e8b9cd3   es02       2.70%     349.2MiB / 15.68GiB   2.17%     656B / 0B   0B / 1.65MB   43
1eee18c882b4   tomcat01   0.14%     101.8MiB / 15.68GiB   0.63%     772B / 0B   0B / 0B       30
16860d36d1af   nginx00    0.00%     1.391MiB / 15.68GiB   0.01%     772B / 0B   0B / 0B       2

思考:kibana如何连接es?涉及到 容器的网络

作业4: docker的可视化

portainer: docker图形化界面管理工具

# docker run -d -p 8081:9000 
--restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
# curl localhost:8081

 可以管理container、images等内容

三、Docker镜像讲解

1. Docker镜像加载原理

UnionFS (联合文件系统)

我们下载的时候看到一层层的下载就是这个。

UnionFs(联合文件系统):Union文件系统(UnionFs)是一种分层、轻量级并且高性能的文件系统,他支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。
Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

**特性**:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。


Docker镜像加载原理 

docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统称作UnionFS。

boots(boot file system)主要包含 bootloader和 Kernel, bootloader主要是引导加 kernel, Linux刚启动时会加bootfs文件系统,在 Docker镜像的最底层是 boots。这一层与我们典型的Linux/Unix系统是一样的,包含boot加載器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs转交给内核,此时系统也会卸载bootfs。

rootfs(root file system),在 bootfs之上。包含的就是典型 Linux系统中
的/dev,/proc,/bin,/etc等标准目录和文件。 rootfs就是各种不同的操作系统发行版,比如 Ubuntu, Centos等等。

为什么Docker的大小比较小

对于个精简的OS,rootfs可以很小,只需要包合最基本的命令,工具和程序库就可以了,因为底层直接用
Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的Linux发行版, boots基本是一致
的, rootfs会有差別,因此不同的发行版可以公用bootfs.
虚拟机是分钟级别,容器是秒级!

2. 分层理解

为什么Docker镜像要采用这种分层的结构呢?
最大的好处,我觉得莫过于资源共享了!比如有多个镜像都从相同的Base镜像构建而来,那么宿主机
只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器
服务了,而且镜像的每一层都可以被共享。
查看镜像分层的方式可以通过docker image inspect 命令。

四、容器数据卷

1. 什么是容器卷

将容器中的部分数据持久化,通过某种映射的方式保存在host上,当容器被删除时,并不影响数据的内容。

作用就是:窗口数据的持久化、实现容器之间的数据共享。

2. 使用数据卷

原文地址:https://www.cnblogs.com/marathoner/p/14288161.html