Docker作为轻量级的虚拟化方式,实现了PaaS平台的高效部署、运维和维护。以下是Docker容器的总览,包括基本概念、容器管理、镜像和仓库管理、资源管理、容器编排管理、容器监控以及容器使用,本文简要介绍Docker基本概念、安装部署以及容器的使用。
容器是一种轻量级、可移植、自包含的软件打包技术,使应用程序几乎可以在任何地方以相同的方式运行。容器提供的镜像包含了应用的所有依赖项,因而从开发到测试再到生产的整个过程中,它都具有可移植性和一致性。
容器与传统的虚拟化技术如VMware、KVM相比,容器本身就是一类应用程序包含其它程序需要的库或者依赖包,在操作系统的用户空间运行,与操作系统其它进程进行隔离。
虚拟机和容器的对比如上图所示,自下到上理解如下:
Docker是将集装箱思想运用到软件打包上,可以将任何应用及其依赖打包成一个轻量级、可移植、自包含的容器。Docker容器可以快速自动化的部署应用,并通过操作系统内核技术(namespaces、cgroups等)为容器提供资源隔离与安全保障。Docker作为轻量级的虚拟化方式,实现了PaaS平台的高效部署、运维和维护。Docker具有以下优点:
Docker采用的是C/S(client/server)架构,Docker客户端使用REST API向Docker Host发送请求,Docker Host端的daemon对请求进行处理,包括构建、运行和分发容器。
Docker使用namespace进行物理上隔离,运行docker的时候会创建一系列namespaces:
Linux cGroups提供了对一组进程及子进程的资源限制、控制和统计的能力,这些资源包括CPU、内存、磁盘和网络等。
[root@tango-01 ~]# cat /proc/cgroups
#subsys_name hierarchy num_cgroups enabled
cpuset 7 3 1
cpu 4 84 1
cpuacct 4 84 1
memory 9 84 1
devices 2 84 1
freezer 8 3 1
net_cls 11 3 1
blkio 10 84 1
perf_event 6 3 1
hugetlb 3 3 1
pids 5 3 1
net_prio 11 3 1
理解Docker容器生命周期需要了解Docker的三个核心概念:
Docker镜像是一个创建Container的只读模板,比如基于Ubuntu镜像可以创建一个Docker镜像,里面只包含基本的操作系统以及应用程序所需要的Apache等。另外,也可以基于Repository中发布的镜像来创建Container镜像。
2) 容器(container)
Docker container是镜像运行时的实体,可以通过Docker API或CLI来创建、运行、删除和维护container。在一个机器中不同的容器可以进行CPU、内存和网络等资源隔离。
3) 仓库(repository)
Docker repository用来存放docker镜像,当用户创建自己的镜像后可以使用push命令将它上传到指定的公有或私有仓库,这样下次再另外一台机器使用镜像时候只需要从仓库上pull下来就可以了。
Docker容器整个生命周期如上图所示:
主机名 | IP | 操作系统 |
---|---|---|
tango-01 | 192.168.112.10 | Centos-7.0_x86_64 |
1)卸载旧版本
[root@tango-01 /]# yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
2)更新yum源
[root@tango-01 yum.repos.d]# wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
<=替换download.docker.com为mirrors.ustc.edu.cn/docker-ce =>
[root@tango-01 yum.repos.d]# sed -i 's#download.docker.com#mirrors.ustc.edu.cn/docker-ce#g' /etc/yum.repos.d/docker-ce.repo
3)安装
[root@tango-01 /]# yum install docker-ce -y
4)启动docker
[root@tango-01 /]# systemctl restart docker
[root@tango-01 /]# systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
Active: active (running) since Tue 2020-09-22 22:57:13 CST; 3s ago
Docs: https://docs.docker.com
Main PID: 1830 (dockerd)
Memory: 40.1M
CGroup: /system.slice/docker.service
└─1830 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
Sep 22 22:57:12 tango-01 dockerd[1830]: time="2020-09-22T22:57:12.993880227+08:00" level=info msg="scheme \"unix\" not registered, fallback to default scheme" module=grpc
Sep 22 22:57:12 tango-01 dockerd[1830]: time="2020-09-22T22:57:12.993894533+08:00" level=info msg="ccResolverWrapper: sending update to cc: {[{unix:///run/co...module=grpc
Sep 22 22:57:12 tango-01 dockerd[1830]: time="2020-09-22T22:57:12.993901989+08:00" level=info msg="ClientConn switching balancer to \"pick_first\"" module=grpc
Sep 22 22:57:13 tango-01 dockerd[1830]: time="2020-09-22T22:57:13.017228516+08:00" level=info msg="Loading containers: start."
Sep 22 22:57:13 tango-01 dockerd[1830]: time="2020-09-22T22:57:13.174544832+08:00" level=info msg="Default bridge (docker0) is assigned with an IP address 17...IP address"
Sep 22 22:57:13 tango-01 dockerd[1830]: time="2020-09-22T22:57:13.225336290+08:00" level=info msg="Loading containers: done."
Sep 22 22:57:13 tango-01 dockerd[1830]: time="2020-09-22T22:57:13.264954414+08:00" level=info msg="Docker daemon" commit=4484c46d9d graphdriver(s)=overlay2 v...on=19.03.13
Sep 22 22:57:13 tango-01 dockerd[1830]: time="2020-09-22T22:57:13.265043951+08:00" level=info msg="Daemon has completed initialization"
Sep 22 22:57:13 tango-01 dockerd[1830]: time="2020-09-22T22:57:13.299028408+08:00" level=info msg="API listen on /var/run/docker.sock"
Sep 22 22:57:13 tango-01 systemd[1]: Started Docker Application Container Engine.
Hint: Some lines were ellipsized, use -l to show in full.
如果想设置开机启动
[root@tango-01 /]# systemctl enable docker.service
5)查看docker版本
[root@tango-01 /]# docker version
Client: Docker Engine - Community
Version: 19.03.13
API version: 1.40
Go version: go1.13.15
Git commit: 4484c46d9d
Built: Wed Sep 16 17:03:45 2020
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 19.03.13
API version: 1.40 (minimum version 1.12)
Go version: go1.13.15
Git commit: 4484c46d9d
Built: Wed Sep 16 17:02:21 2020
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.3.7
GitCommit: 8fba4e9a7d01810a393d5d25a3621dc101981175
runc:
Version: 1.0.0-rc10
GitCommit: dc9208a3303feef5b3839f4323d9beb36df0a9dd
docker-init:
Version: 0.18.0
GitCommit: fec3683
6)配置docker镜像加速
[root@tango-01 /]# docker run hello-world
Unable to find image 'hello-world:latest' locally
docker: Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers).
See 'docker run --help'.
有时候在pull镜像时候无法访问,可以配置docker镜像加速,编辑以下文件:
[root@tango-01 /]# vi /etc/docker/daemon.json
{
"registry-mirrors":["https://docker.mirrors.ustc.edu.cn"]
}
修改完成后reload配置文件,重启docker
[root@tango-01 ~]# systemctl daemon-reload
[root@tango-01 ~]#
[root@tango-01 ~]# systemctl restart docker
查看docker信息,看到Registry Mirrors:已经生效
[root@tango-01 ~]# docker info
Client:
Debug Mode: false
Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 19.03.13
Storage Driver: overlay2
Backing Filesystem: xfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 8fba4e9a7d01810a393d5d25a3621dc101981175
runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd
init version: fec3683
Security Options:
seccomp
Profile: default
Kernel Version: 3.10.0-693.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 976.3MiB
Name: tango-01
ID: HF65:GBPP:MJ7C:CRRQ:JIM5:JXXP:7VXY:6YIH:CUCH:74RQ:HCLK:UY5E
Docker Root Dir: /var/lib/docker
Debug Mode: false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Registry Mirrors:
https://docker.mirrors.ustc.edu.cn/
Live Restore Enabled: false
7)测试运行
[root@tango-01 ~]# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Downloading
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete
Digest: sha256:4cf9c47f86df71d48364001ede3a4fcd85ae80ce02ebad74156906caff5378bc
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
本地registry中没有,会从Registry Mirrors中拉取镜像
1)使用docker create命令创建容器
[root@tango-01 ~]# docker create -it ubuntu:latest
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
e6ca3592b144: Pull complete
534a5505201d: Pull complete
990916bd23bb: Pull complete
Digest: sha256:cbcf86d7781dbb3a6aa2bcea25403f6b0b443e20b9959165cf52d2cc9608e4b9
Status: Downloaded newer image for ubuntu:latest
72c239912c08e03552393575dce207d6a2a5f426732bccb0f6039b7c308fe7af
2)查看所有容器
[root@tango-01 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
72c239912c08 ubuntu:latest "/bin/bash" 2 minutes ago Created jolly_margulis
4791aecec8f1 hello-world "/hello" 12 minutes ago Exited (0) 12 minutes ago busy_feynman
3)查看你容器详细信息/ip
[root@tango-01 ~]# docker container inspect 72c239912c08
[
{
"Id": "72c239912c08e03552393575dce207d6a2a5f426732bccb0f6039b7c308fe7af",
"Created": "2020-09-23T14:43:43.187480507Z",
"Path": "/bin/bash",
"Args": [],
"State": {
"Status": "created",
"Running": false,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 0,
"ExitCode": 0,
"Error": "",
"StartedAt": "0001-01-01T00:00:00Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
1)使用ubuntu镜像启动一个容器,参数为以命令行模式进入该容器:
[root@tango-01 ~]# docker run -itd ubuntu /bin/bash
a910fdcf16e588d0a5283c0aed7de5ea30eb2e4efab0b2563d4bdf1f5f1ca70f
参数说明:
注:加了 -d 参数默认不会进入容器,想要进入容器需要使用指令 docker exec
2)查看正在运行的容器
[root@tango-01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a910fdcf16e5 ubuntu "/bin/bash" 35 seconds ago Up 34 seconds nervous_wozniak
[root@tango-01 ~]# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a910fdcf16e5 ubuntu "/bin/bash" 46 seconds ago Up 45 seconds nervous_wozniak
3)停止一个容器
$ docker stop <容器 ID>
[root@tango-01 ~]# docker stop a910fdcf16e5
a910fdcf16e5
4)停止的容器可以通过 docker restart 重启:
$ docker restart <容器 ID>
[root@tango-01 ~]# docker restart a910fdcf16e5
a910fdcf16e5
[root@tango-01 ~]# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a910fdcf16e5 ubuntu "/bin/bash" 3 minutes ago Up 4 seconds nervous_wozniak
在使用 -d 参数时,容器启动后会进入后台。此时想要进入容器,可以通过以下指令进入:docker attach和docker exec。推荐使用docker exec命令,因为此退出容器终端,不会导致容器的停止。
1)attach 命令
[root@tango-01 ~]# docker attach a910fdcf16e5
root@a910fdcf16e5:/# exit
exit
[root@tango-01 ~]#
注意: 如果从这个容器退出,会导致容器的停止。
2)exec命令
[root@tango-01 ~]# docker exec -it a910fdcf16e5 /bin/bash
root@a910fdcf16e5:/# exit
exit
[root@tango-01 ~]#
[root@tango-01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a910fdcf16e5 ubuntu "/bin/bash" 8 minutes ago Up 16 seconds nervous_wozniak
注意: 如果从这个容器退出,不会导致容器的停止
删除容器使用docker rm命令:
[root@tango-01 /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a910fdcf16e5 ubuntu "/bin/bash" 17 minutes ago Up 8 minutes nervous_wozniak
[root@tango-01 /]# docker rm -f a910fdcf16e5
a910fdcf16e5
prune命令可以清理掉所有处于终止状态的容器:
[root@tango-01 /]# docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] N
Total reclaimed space: 0B
1)导出容器
如果要导出本地某个容器,可以使用 docker export 命令:
[root@tango-01 /]# mkdir /tmp/docker
[root@tango-01 /]# docker export a910fdcf16e5 > /tmp/docker/ubuntu.tar
[root@tango-01 /]# ll /tmp/docker/
total 73496
-rw-r--r-- 1 root root 75257344 Sep 23 23:05 ubuntu.tar
这样将导出容器快照到本地文件。
2)导入容器快照
可以使用 docker import 从容器快照文件中再导入为镜像,以下实例将快照文件 ubuntu.tar 导入到镜像 test/ubuntu:v1:
[root@tango-01 /]# cat /tmp/docker/ubuntu.tar |docker import - test/ubuntu:v1
sha256:2256fb90ca54710fc45c6544495faaf6735a1f3d7856ba17e04e40df5b32e2cd
-p参数端口映射
[root@tango-01 /]# docker run -d -p 8080:80 nginx:latest
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
d121f8d1c412: Downloading
ebd81fc8c071: Download complete
655316c160af: Download complete
d15953c0e0f8: Download complete
2ee525c5c3cc: Download complete
latest: Pulling from library/nginx
d121f8d1c412: Pull complete
ebd81fc8c071: Pull complete
655316c160af: Pull complete
d15953c0e0f8: Pull complete
2ee525c5c3cc: Pull complete
Digest: sha256:c628b67d21744fce822d22fdcc0389f6bd763daac23a6b77147d0712ea7102d0
Status: Downloaded newer image for nginx:latest
14be935835a3318a4279c8e0e3c69c73e79e139842d59fc8966b65abef60ba51
[root@tango-01 /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
14be935835a3 nginx:latest "/docker-entrypoint.…" 4 minutes ago Up 4 minutes 0.0.0.0:8080->80/tcp admiring_galileo
1)在docker容器中运行一个 Python Flask 应用来运行一个web应用
[root@tango-01 ~]# docker pull training/webapp
Using default tag: latest
latest: Pulling from training/webapp
Image docker.io/training/webapp:latest uses outdated schema1 manifest format. Please upgrade to a schema2 image for better future compatibility. More information at https://docs.docker.com/registry/spec/deprecated-schema-v1/
e190868d63f8: Downloading [==> ] 3.152MB/65.77MB
909cd34c6fd7: Pulling fs layer
0b9bfabab7c1: Downloading
a3ed95caeb02: Waiting
10bbbc0fc0ff: Waiting
fca59b508e9f: Waiting
e7ae2541b15b: Waiting
9dd97ef58ce9: Waiting
a4c1b0cb7af7: Waiting
latest: Pulling from training/webapp
Image docker.io/training/webapp:latest uses outdated schema1 manifest format. Please upgrade to a schema2 image for better future compatibility. More information at https://docs.docker.com/registry/spec/deprecated-schema-v1/
e190868d63f8: Pull complete
909cd34c6fd7: Pull complete
0b9bfabab7c1: Pull complete
a3ed95caeb02: Pull complete
10bbbc0fc0ff: Pull complete
fca59b508e9f: Pull complete
e7ae2541b15b: Pull complete
9dd97ef58ce9: Pull complete
a4c1b0cb7af7: Pull complete
Digest: sha256:06e9c1983bd6d5db5fba376ccd63bfa529e8d02f23d5079b8f74a616308fb11d
Status: Downloaded newer image for training/webapp:latest
docker.io/training/webapp:latest
2)运行容器
[root@tango-01 ~]# docker run -d -P training/webapp python app.py
c39cf512b3f9a866dc7ea89e50cf6c75dbf8e5ab942d4c9db8e0c52c56b28c1e
[root@tango-01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c39cf512b3f9 training/webapp "python app.py" 10 seconds ago Up 7 seconds 0.0.0.0:32768->5000/tcp pensive_liskov
参数说明:
1)使用 docker ps 来查看我们正在运行的容器
[root@tango-01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c39cf512b3f9 training/webapp "python app.py" 10 seconds ago Up 7 seconds 0.0.0.0:32768->5000/tcp pensive_liskov
这里多了端口信息:0.0.0.0:32768->5000/tcp,Docker开放了5000端口(默认Python Flask端口)映射到主机端口 32768 上。可以通过浏览器访问WEB应用
通过docker ps命令可以查看到容器的端口映射,也可以使用快捷方式 docker port查看指定(ID 或者名字)容器的某个确定端口映射到宿主机的端口号。
[root@tango-01 ~]# docker port c39cf512b3f9
5000/tcp -> 0.0.0.0:32768
docker logs [ID或者名字] 可以查看容器内部的标准输出
[root@tango-01 ~]# docker logs -f c39cf512b3f9
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
192.168.112.1 - - [24/Sep/2020 02:55:42] "GET / HTTP/1.1" 200 -
192.168.112.1 - - [24/Sep/2020 02:55:42] "GET /favicon.ico HTTP/1.1" 404 -
1)使用 docker top 来查看容器内部运行的进程
[root@tango-01 ~]# docker top c39cf512b3f9
UID PID PPID C STIME TTY TIME CMD
root 6717 6700 0 10:52 ? 00:00:00 python app.py
2)检查 WEB 应用程序
使用docker inspect来查看Docker的底层信息,它会返回一个JSON文件记录着Docker容器的配置和状态信息。
[root@tango-01 ~]# docker inspect c39cf512b3f9
[
{
"Id": "c39cf512b3f9a866dc7ea89e50cf6c75dbf8e5ab942d4c9db8e0c52c56b28c1e",
"Created": "2020-09-24T02:52:30.593848613Z",
"Path": "python",
"Args": [
"app.py"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 6717,
"ExitCode": 0,
"Error": "",
"StartedAt": "2020-09-24T02:52:33.034745608Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
使用docker stop命令停止容器
[root@tango-01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c39cf512b3f9 training/webapp "python app.py" 10 minutes ago Up 9 minutes 0.0.0.0:32768->5000/tcp pensive_liskov
[root@tango-01 ~]# docker stop c39cf512b3f9
c39cf512b3f9
已经停止的容器,可以使用命令docker start来启动
[root@tango-01 ~]# docker start c39cf512b3f9
c39cf512b3f9
docker ps -l查询最后一次创建的容器:
[root@tango-01 ~]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c39cf512b3f9 training/webapp "python app.py" 11 minutes ago Up 11 seconds 0.0.0.0:32769->5000/tcp pensive_liskov
使用 docker rm 命令来删除不需要的容器
[root@tango-01 ~]# docker rm c39cf512b3f9
Error response from daemon: You cannot remove a running container c39cf512b3f9a866dc7ea89e50cf6c75dbf8e5ab942d4c9db8e0c52c56b28c1e. Stop the container before attempting removal or force remove
可以使用“docker rm –f”强制删除
参考资料
转载请注明原文地址:https://blog.csdn.net/solihawk/article/details/121046419
文章会同步在公众号“牧羊人的方向”更新,感兴趣的可以关注公众号,谢谢!