一、Docker概述

Docker 容器是一个开源的应用容器引擎,让开发者可以以统一的方式打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何安装了docker引擎的服务器上(包括流行的Linux机器、windows机器),也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何借口(类似 iPhone 的 app)。几乎没有性能开销,可以很容易地在机器和数据中心中运行。最重要的是,他们不依赖于任何语言、框架包括系统。

Docker是PaaS提供商dotCloud开源的一个基于LXC的高级容器引擎,源代码托管在 Github 上, 基于go语言并遵从Apache2.0协议开源。

沙箱也叫沙盒,英文名sandbox。在计算机领域指一种虚拟技术,且多用于计算机安全技术,是一种安全机制,为运行中的程序提供的隔离环境。通常是作为一些来源不可信、具破坏力或无法判定程序意图的程序提供实验之用。

LXC为Linux Container的简写。可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性。LXC在资源管理方面依赖于Linux内核的cgroups子系统,cgroups子系统是Linux内核提供的一个基于进程组的资源管理的框架,可以为特定的进程组限定可以使用的资源。LXC在隔离控制方面依赖于Linux内核的namespace特性,具体而言就是在clone时加入相应的flag(NEWNS NEWPID等等)。

特性

Docker容器与其他的容器技术都是大致类似的。但是,Docker在一个单一的容器内捆绑了关键的应用程序组件,这也就让这容器可以在不同平台和云计算之间实现便携性。其结果就是,Docker就成为了需要实现跨多个不同环境运行的应用程序的理想容器技术选择。

Docker还可以让使用微服务的应用程序得益,所谓微服务就是把应用程序分解成为专门开发的更小服务。 这些服务使用通用的REST API来进行交互。使用完全封装Docker容器的开发人员可以针对采用微服务的应用程序开发出一个更为高效的分发模式。

Docker用途,目前有三大类

  • 1、提供一次性的环境。比如,本地测试他人的软件、持续集成的时候提供单元测试和构建的环境。

  • 2、提供弹性的云服务。因为 Docker 容器可以随开随关,很适合动态扩容和缩容。

  • 3、组建微服务架构。通过多个容器,一台机器可以跑多个服务,因此在本机就可以模拟出微服务架构。

Docker安装:www.jianshu.com/p/fd7a550ce94f

二、Docker 镜像原理

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境的开发软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。

UnionFS(联合文件系统)

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

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

Docker 镜像加载原理

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

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

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

对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host(宿主机)的kernel,自己只需要提供rootfs就行了,由此可见对于不同的Linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。

分层的镜像

以我们的pull为例,在下载的过程中我们可以看到docker的镜像好像是在一层一层的在下载

[root@localhost ~]# docker pull mysql
Using default tag: latest
latest: Pulling from library/mysql
a330b6cecb98: Pull complete
9c8f656c32b8: Pull complete
88e473c3f553: Pull complete
062463ea5d2f: Pull complete
daf7e3bdf4b6: Pull complete
1839c0b7aac9: Pull complete
cf0a0cfee6d0: Pull complete
1b42041bb11e: Pull complete
10459d86c7e6: Pull complete
b7199599d5f9: Pull complete
1d6f51e17d45: Pull complete
50e0789bacad: Pull complete
Digest: sha256:99e0989e7e3797cfbdb8d51a19d32c8d286dd8862794d01a547651a896bcf00c
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest

Docker 镜像联合文件系统分层

采用这种分层结构最大的一个好处就是共享资源,比如有多个镜像都从相同的base镜像构建而来,那么宿主机只需要在磁盘上保存一份base镜像,同时内存中也只需要加载一份base镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

docker 镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作 “容器层” ,“容器层” 之下的都叫镜像层。

三、Docker的常用命令

帮助命令

docker version          # 显示docker的版本信息
docker info # 显示docker的系统信息,包括镜像和容器数量
docker 命令 --help # 帮助命令

帮助文档的地址:docs.docker.com/reference/

镜像命令

  • docker images:列出当前系统所有镜像

[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 231d40e811cd 22 months ago 126MB
centos latest 0f3e07c0138f 24 months ago 220MB
hello-world latest fce289e99eb9 2 years ago 1.84kB

#解释
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的id
CREATED 镜像的创建时间
SIZE 镜像的大小


[root@localhost ~]# docker images --help

Usage: docker images [OPTIONS] [REPOSITORY[:TAG]]

List images

# 可选项
Options:
-a, --all #列出所有的镜像
--digests Show digests
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print images using a Go template
--no-trunc Don't truncate output
-q, --quiet #只显示id
  • docker search:搜索镜像

[root@localhost ~]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation11461 [OK]
mariadb MariaDB Server is a high performing open sou4351 [OK]
mysql/mysql-server Optimized MySQL Server Docker images. Create848 [OK]
phpmyadmin phpMyAdmin - A web interface for MySQL and M332 [OK]

#可选项
[root@localhost ~]# docker search --help

Usage: docker search [OPTIONS] TERM

Search the Docker Hub for images

Options:
-f, --filter filter # --filter=STARS=5000 #搜索出来的镜像就是STARS>5000
--format string Pretty-print search using a Go template
--limit int Max number of search results (default 25)
--no-trunc Don
[root@localhost ~]# docker search mysql --filter=STARS=5000
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 11461 [OK]
  • docker pull:下载镜像

#下载镜像 docker pull 镜像名[:tag]
[root@localhost ~]# docker pull mysql
Using default tag: latest #如果不写tag,默认就是latest
latest: Pulling from library/mysql
a330b6cecb98: Pull complete #分层下载, docker image的核心
9c8f656c32b8: Pull complete
88e473c3f553: Pull complete
062463ea5d2f: Pull complete
daf7e3bdf4b6: Pull complete
1839c0b7aac9: Pull complete
cf0a0cfee6d0: Pull complete
1b42041bb11e: Pull complete
10459d86c7e6: Pull complete
b7199599d5f9: Pull complete
1d6f51e17d45: Pull complete
50e0789bacad: Pull complete
Digest: sha256:99e0989e7e3797cfbdb8d51a19d32c8d286dd8862794d01a547651a896bcf00c #签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest #真实地址

docker pull mysql 等价于 docker pull docker.io/library/mysql:latest

#指定版本下载
docker pull mysql:5.7
  • docker rmi:删除镜像

[root@localhost ~]# docker rmi -f 镜像id              #删除指定的镜像

[root@localhost ~]# docker rmi -f 镜像id 镜像id #删除多个镜像

[root@localhost ~]# docker rmi -f $(docker images -aq) #删除全部镜像

容器命令

  • docker run [可选参数] image:新建容器并启动

[root@localhost ~]# docker run --help

Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

Run a command in a new container

Options:
--add-host list Add a custom host-to-IP mapping (host:ip)
-a, --attach list Attach to STDIN, STDOUT or STDERR
--blkio-weight uint16 Block IO (relative weight), between 10 and 1000, or 0 to disable
(default 0)
--blkio-weight-device list Block IO weight (relative device weight) (default [])
--cap-add list Add Linux capabilities
--cap-drop list Drop Linux capabilities
--cgroup-parent string Optional parent cgroup for the container
--cgroupns string Cgroup namespace to use (host|private)
'host': Run the container in the Docker host's cgroup namespace
'private': Run the container in its own private cgroup namespace
'': Use the cgroup namespace as configured by the
default-cgroupns-mode option on the daemon (default)
--cidfile string # 把容器 id 写入到指定文件
--cpu-period int Limit CPU CFS (Completely Fair Scheduler) period
--cpu-quota int Limit CPU CFS (Completely Fair Scheduler) quota
--cpu-rt-period int Limit CPU real-time period in microseconds
--cpu-rt-runtime int Limit CPU real-time runtime in microseconds
-c, --cpu-shares int # 设置 cpu 使用权重
--cpus decimal Number of CPUs
--cpuset-cpus string # cpu 绑定
--cpuset-mems string MEMs in which to allow execution (0-3, 0,1)
-d, --detach # 后台运行容器
--detach-keys string Override the key sequence for detaching a container
--device list Add a host device to the container
--device-cgroup-rule list Add a rule to the cgroup allowed devices list
--device-read-bps list Limit read rate (bytes per second) from a device (default [])
--device-read-iops list Limit read rate (IO per second) from a device (default [])
--device-write-bps list Limit write rate (bytes per second) to a device (default [])
--device-write-iops list Limit write rate (IO per second) to a device (default [])
--disable-content-trust Skip image verification (default true)
--dns list # 设置 dns
--dns-option list Set DNS options
--dns-search list # 设置 dns 域搜索
--domainname string Container NIS domain name
--entrypoint string Overwrite the default ENTRYPOINT of the image
-e, --env list # 定义环境变量
--env-file list # 从指定文件读取变量值
--expose list # 指定对外提供服务端口
--gpus gpu-request GPU devices to add to the container ('all' to pass all GPUs)
--group-add list Add additional groups to join
--health-cmd string Command to run to check health
--health-interval duration Time between running the check (ms|s|m|h) (default 0s)
--health-retries int Consecutive failures needed to report unhealthy
--health-start-period duration Start period for the container to initialize before starting
health-retries countdown (ms|s|m|h) (default 0s)
--health-timeout duration Maximum time to allow one check to run (ms|s|m|h) (default 0s)
--help Print usage
-h, --hostname string # 设置容器主机名
--init Run an init inside the container that forwards signals and reaps
processes
-i, --interactive # 保持标准输出开启即使没有 attached
--ip string IPv4 address (e.g., 172.30.100.104)
--ip6 string IPv6 address (e.g., 2001:db8::33)
--ipc string IPC mode to use
--isolation string Container isolation technology
--kernel-memory bytes Kernel memory limit
-l, --label list Set meta data on a container
--label-file list Read in a line delimited file of labels
--link list # 添加链接到另外一个容器
--link-local-ip list Container IPv4/IPv6 link-local addresses
--log-driver string Logging driver for the container
--log-opt list Log driver options
--mac-address string Container MAC address (e.g., 92:d0:c6:0a:29:33)
-m, --memory bytes # 内存限制
--memory-reservation bytes Memory soft limit
--memory-swap bytes Swap limit equal to memory plus swap: '-1' to enable unlimited swap
--memory-swappiness int Tune container memory swappiness (0 to 100) (default -1)
--mount mount Attach a filesystem mount to the container
--name string # 设置容器名
--network network Connect a container to a network
--network-alias list Add network-scoped alias for the container
--no-healthcheck Disable any container-specified HEALTHCHECK
--oom-kill-disable Disable OOM Killer
--oom-score-adj int Tune host's OOM preferences (-1000 to 1000)
--pid string PID namespace to use
--pids-limit int Tune container pids limit (set -1 for unlimited)
--platform string Set platform if server is multi-platform capable
--privileged # 提供更多的权限给容器
-p, --publish list # 指定端口映射 -P 8080:8080
-P, --publish-all # 自动映射容器对外提供服务的端口
--pull string Pull image before running ("always"|"missing"|"never") (default
"missing")
--read-only Mount the container's root filesystem as read only
--restart string Restart policy to apply when a container exits (default "no")
--rm # 如果容器退出自动移除和 -d 选项冲突
--runtime string Runtime to use for this container
--security-opt list Security Options
--shm-size bytes Size of /dev/shm
--sig-proxy Proxy received signals to the process (default true)
--stop-signal string Signal to stop a container (default "SIGTERM")
--stop-timeout int Timeout (in seconds) to stop a container
--storage-opt list Storage driver options for the container
--sysctl map Sysctl options (default map[])
--tmpfs list Mount a tmpfs directory
-t, --tty # 分配伪终端
--ulimit ulimit Ulimit options (default [])
-u, --user string # 指定运行容器的用户 uid 或者用户名
--userns string User namespace to use
--uts string UTS namespace to use
-v, --volume list Bind mount a volume
--volume-driver string Optional volume driver for the container
--volumes-from list # 从指定容器挂载卷
-w, --workdir string # 指定容器工作目录
-it # 使用交互方式运行,进入容器
#启动并进入容器
[root@localhost root]# docker run -it centos /bin/bash
[root@26c8c9d0c6ac /]# ls #查看容器内的centos,基础版本,很多命令都是不完善的
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@26c8c9d0c6ac /]#
# 从容器退出到主机
[root@26c8c9d0c6ac /]# exit
exit
[root@localhost root]#
  • docker ps:列出所有运行的容器

# docker ps 命令
# 列出当前正在运行的容器
-a # 列出当前正在运行的容器+带出历史运行过的容器
-n=? # 显示最近创建的容器
-q # 只显示容器的编号

[root@localhost root]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@localhost root]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
26c8c9d0c6ac centos "/bin/bash" 3 minutes ago Exited (0) 2 minutes ago hopeful_morse
dadcffa26260 centos "/bin/bash" 11 minutes ago Exited (127) 9 minutes ago pedantic_curran
29508d9441ae nginx "nginx -g 'daemon of…" 21 months ago Exited (0) 21 months ago web
1097ce5d6d8b centos "/bin/bash" 21 months ago Exited (0) 21 months ago tender_shaw
9a90c44eb21e hello-world "/hello" 21 months ago Exited (0) 21 months ago interesting_brown
[root@localhost root]#
  • 退出容器

exit            #直接容器停止并退出

Ctrl + P + Q # 容器不停止退出
  • docker rm:删除容器

docker rm 容器id              # 删除指定的容器,不能删除正在运行的容器,如果要强制删除 rm -f 

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

docker ps -a | xargs docker rm # 删除所有的容器
  • 启动和停止容器

docker start 容器id       # 启动容器

docker restart 容器id # 重启容器

docker stop 容器id # 停止当前正在运行的容器

docker kill 容器id # 强制停止当前容器

常用的其他命令

  • 后台启动容器

# docker run -d 容器名[root@localhost ~]# docker run -d centos# docker ps 发现centos容器停止了# docker 容器使用后台运行,就必须要有一个前台进程,docker发现没有前台应用,就会停止# nginx 容器启动之后,发现自己没有提供服务,就会立刻停止
  • 查看日志

docker logs -f -t --tail 容器id

#显示看10条日志
docker logs -f -t --tail 10 容器id
  • 查看容器中进程信息

docker top 容器id
  • 查看镜像元数据

docker inspect 容器id
  • 进入正在运行的容器

docker exec -it 容器id /bin/bash
docker attach 容器id /bin/bash
docker exec         # 进入容器开启一个新的终端,可以在里面操作(常用)
docker attach # 进入容器正在执行的终端,不会启动新的进程
  • 从容器内拷贝文件到主机

docker cp 容器id:容器内路径 目的主机路径
  • docker commit:提交容器成为一个信息镜像

[root@localhost ~]# docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[tag]

Volume 数据持久化命令

docker run -it -v 主机目录:容器内目录

[root@localhost ~]# docker run -it -v /home/test:/home centos /bin/bash

具名挂载和匿名挂载

  • 1、匿名挂

docker run -d -P --name nginx01 -v /etc/nginx nginx 

-v 容器内路径

注: 由上图可以看到,VOLUME NAME 有的是随机生成的字符串,对于这种就是匿名挂载,因为-v的时候只写了容器内的路径看,而没有写容器外的路径。

  • 2、具名挂载

docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx 语法: -v 卷名:容器内路径

查看一下这个卷

docker volumn inspect juming-nginx

注意:

  • 所有docker容器内的卷,没有指定目录的情况下都是在 /var/lib/docker/volumes/XXX

  • docker volumn ls 查看所有的卷都在这个位置/var/lib/docker/volumns

通过具名挂载可以方便的找到我们的一个卷,大多数情况在使用的,不建议大家使用匿名挂载

如何确定是匿名挂载还是具名挂载呢?

-v 容器内路径                #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载

拓展

  • 1、通过 -v 容器内路径:ro rw 改变读写权限

ro readonly  #只读
rw readwrite #可读可写
  • 2、一旦这个设定了容器权限,容器对我们挂载出来的内容就有限定了

docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro  nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
  • 3、ro 只要看到ro就说明这个路径只能通过宿主机来改变,容器内部是无法操作的。

docker 安装MySQL

  • 查找MySQL镜像:

docker search mysql
  • 拉起MySQL镜像(:5.7 表示5.7版本)

docker pull mysql:5.7
  • 运行MySQL容器

docker run -d -p 3306:3306 --privileged=true -v /docker/mysql/conf/my.cnf:/etc/my.cnf -v /docker/mysql/data:/var/lib/mysql -eMYSQL_ROOT_PASSWORD=123456 --name mysql mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci

参数说明:

  • run:run 是运行一个容器

  • -d:表示后台运行

  • -p:表示容器内部端口和服务器端口映射关联

  • --privileged=true:设值MySQL 的root用户权限, 否则外部不能使用root用户登陆

  • -v /docker/mysql/conf/my.cnf:/etc/my.cnf:将服务器中的my.cnf配置映射到docker中的/docker/mysql/conf/my.cnf配置

  • -v /docker/mysql/data:/var/lib/mysql:同上,映射数据库的数据目录, 避免以后docker删除重新运行MySQL容器时数据丢失

  • -e MYSQL_ROOT_PASSWORD=123456:设置MySQL数据库root用户的密码

  • --name mysql:设值容器名称为mysql

  • mysql:5.7:表示从docker镜像mysql:5.7中启动一个容器

  • --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci:设值数据库默认编码

新建MySQL用户

  • 先进入容器

docker exec -it mysql bash
  • 执行MySQL命令, 输入root密码, 连接MySQL

mysql -uroot -p
  • 输入密码后, 执行下面命令创建新用户 (用户名: test , 密码: test123)

GRANT ALL PRIVILEGES ON *.* TO 'test'@'%' IDENTIFIED BY 'test123' WITH GRANT OPTION;

阿里云的话远程访问记得防火墙开 3306 端口 !!!!

参考: www.cnblogs.com/xinzaiyuan/p/12608698.html

blog.csdn.net/wangmx1993328/article/details/81735070

www.cnblogs.com/asxf/p/11102949.html

www.cnblogs.com/wjw1014/p/12149399.html

举报/反馈

高级互联网专家

8.7万获赞 2.9万粉丝
互联网软件“卓越技术顾问”,顶级软件架构开发者(承接各类软件项目开发,欢迎合作)<网站、管理后台、app、小程序、服务系统、技术支持等>!
科技领域创作者
关注
0
0
收藏
分享