linux运维、架构之路-Docker架构原理
一、Docker架构原理介绍
Docker使用了C/S架构,客户端与守护进程通信,Docker守护进程负责构建,运行和分发Docker容器。Docker客户端和守护进程可以在同一个系统上运行,也可以将Docker客户端连接到远程Docker守护进程。Docker客户端和守护进程使用REST API通过UNIX套接字或网络接口进行通信。
二、Docker介绍
Docker的英文翻译是”搬运工“的意思,他搬运的东西就是我们常说的集装箱Container,Container里面装的是任意类型的App,我们的开发人员可以通过Docker 将App变成一种标准化的、可移植的、自管理的组件,我们可以在任何主流的操作系统中开发、调试和运行。Docker和虚拟机比较类似,只是更加轻量级,更加方便使用。
1、Docker和虚拟机区别:
- 虚拟化技术依赖的是物理CPU和内存,是硬件级别的;而Docker是构建在操作系统层面的,利用操作系统的容器化技术,所以Docker同样的可以运行在虚拟机上面。
- 虚拟机中的系统就是我们常说的操作系统镜像,比较复杂;而Docker比较轻量级,我们可以使用Docker部署一个独立的Redis,就像类似于在虚拟机当中安装一个Redis应用,但是我们用Docker部署的应用是完全隔离的。
- 在传统的虚拟化技术是通过快照来保存的;而Docker引用了类似于源码的管理机制,将容器的快照历史版本一一记录下来,切换成本低。
- 传统的虚拟化技术在构建系统的时候非常复杂;而Docker可以通过一个简单的Dockerfile文件来构建整个容器,更重要的是Dockerfile可以手动编写,这样应用开发人员可以通过发布Dockerfile来定义应用的环境和依赖,这样对于持续交付非常有利。
2、Docker安装
①安装指定版本docker
#docker官方提供了安装脚本,我们确认好版本就可以直接安装# export VERSION=18.06 curl -fsSL "https://get.docker.com/" | bash -s -- --mirror Aliyun
②设置overlay2为默认存储驱动,并配置加速器
mkdir -p /etc/docker/ cat > /etc/docker/daemon.json <<EOF { "exec-opts": ["native.cgroupdriver=systemd"], "registry-mirrors": ["https://hjvrgh7a.mirror.aliyuncs.com"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2" } EOF
要添加harbor仓库时需要在添加下面一行 "insecure-registries": ["harbor.demon.com"],默认docker hub需要https协议,使用上面配置不需要配置https。
③设置开机自启并设置docker命令补全
yum install -y epel-release bash-completion && cp /usr/share/bash-completion/completions/docker /etc/bash_completion.d/
systemctl enable --now docker
三、Docker基本操作
1、常用命令
①Docker镜像管理
- 搜索镜像:docker search
- 获取镜像:docker pull
- 查看镜像:docker images
- 删除镜像:docker rmi
- 构建镜像:docker build -t <镜像名>
②Docker容器管理
- 启动容器:docker run –name -h hostname
- docker run -d -P nginx
- -d运行在后台
- -P 代表随机映射
- nginx 镜像的名称
- 停止容器:docker stop CONTAINER ID
- 查看容器:docker ps -a -l
- 进入容器:docker exec | docker attach |nsenter
- 删除容器:docker rm
- 查看容器日志:docker logs CONTAINER ID
- 杀死所有正在运行的容器:docker kill $(docker ps -a -q)
- 删除所有容器(只有先停止才可以删除):docker rm $(docker ps -a -q)
③Docker 网络访问
- 随机映射:docker run -P
- 指定映射:
- -p hostPort:containerPort
- -p ip:hostPort:containerPort
④Docker 查看容器映射信息
- docker port mynginx #容器名称
- 80/tcp -> 192.168.56.100:81
- docker port 65439bce352e #容器ID
- 80/tcp -> 192.168.56.100:81
⑤镜像导出导入
- docker save nginx:latest > /home/nginx.tar
- docker load < /home/nginx.tar
四、Docker 数据共享与持久化
1、数据卷 (Data Volumes)
数据卷是一个可供一个容器或多个容器使用的特殊目录,数据卷的使用,类似于NFS挂载,镜像中被指定为挂载点的目录会隐藏掉,能显示看的是挂载的数据卷。
- 数据卷可以在容器之间共享和重用
- 对数据卷的修改会马上生效
- 对数据卷的更新,不会影响镜像
- 数据卷默认会一直存在,即使容器被删除
①创建一个数据卷
[root@docker ~]# docker volume create my-volume
my-volume
②查看数据卷
[root@docker ~]# docker volume ls
DRIVER VOLUME NAME
local my-volume
如果使用的Docker有容器在运行,这里可能会不止一个。但是如果不添加-v参数,当容器停止或者删除时,volume同时也会被删除。
③使用inspect
查看指定数据卷的信息
[root@docker ~]# docker volume inspect my-volume [ { "CreatedAt": "2020-01-17T15:54:55+08:00", "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/my-volume/_data", "Name": "my-volume", "Options": {}, "Scope": "local" } ]
④启动一个挂载数据卷的容器
docker run -d --name demon -v my-volume:/var/lib/mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql:5.7
- #参数说明 run 启动并创建容器 -d 后台运行 --name 设置容器名称 -v 挂载数据卷 -e 设置命令(因为mysql默认需要设置密码,使用这个变量是可以不设置密码的) mysql:5.7 为mysql的镜像版本
查看容器:
[root@docker ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2cf78ef9dfe7 mysql:5.7 "docker-entrypoint.s…" 4 minutes ago Up 4 minutes 3306/tcp, 33060/tcp demon
查看容器中挂载详情:
[root@docker ~]# docker inspect demon
#此处省略1万字…… "Mounts": [ { "Type": "volume", "Name": "my-volume", "Source": "/var/lib/docker/volumes/my-volume/_data", "Destination": "/var/lib/mysql", "Driver": "local", "Mode": "z", "RW": true, "Propagation": "" } ],
从配置中我们可以看到容器挂载了一个名为my-volume的存储卷,并且挂载到/var/lib/mysql目录下。
⑤进入容器验证
[root@docker ~]# docker exec -it demon /bin/bash root@2cf78ef9dfe7:/# mysql -u root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.7.29 MySQL Community Server (GPL) Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 4 rows in set (0.00 sec) mysql> create database test; Query OK, 1 row affected (0.00 sec) mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | test | +--------------------+ 5 rows in set (0.00 sec)
⑥删除demon的数据库容器
[root@docker ~]# docker rm -f demon #删除容器 demon #重新创建容器 [root@docker ~]# docker run -d --name demon -v my-volume:/var/lib/mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql:5.7 70d4d1da8414071c9ed067fb88fa8acb1b781e7d85a54cfbf848405abc1d8d35 [root@docker ~]# docker exec -it demon /bin/bash root@70d4d1da8414:/# mysql -u root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.7.29 MySQL Community Server (GPL) Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | test | +--------------------+ 5 rows in set (0.00 sec)
数据卷是被设计用来持久化数据的,它的生命周期独立于容器,Docker不会在容器被删除后自动删除数据卷,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的数据卷。如果需要删除在删除容器同时移除数据卷。可以在删除容器时使用docker rm -v命令。无主的数据卷可能会占用很多空间。
⑦删除数据卷
- 删除指定名称数据卷
- docker volume rm my-volume
- 删除所有数据卷
- docker volume prune
2、挂载主机目录 (Bind Mounts)
Docker持久化存储除了有逻辑卷还有一个是挂载目录,挂载一个主机目录作为数据卷,可以使用--mount或者使用-v 指定目录(-v也可以指定数据卷) -p参数为端口映射。
①创建一个nginx容器并挂载数据卷
docker run -d --name demon-nginx -p 80:80 -v /data:/data nginx
②进入容器验证
root@docker ~]# docker exec -it demon-nginx /bin/bash root@8029fddd8a1d:/# cd /data root@8029fddd8a1d:/data# ls root@8029fddd8a1d:/data# echo "mount nginx test" >index.html root@8029fddd8a1d:/data# exit exit [root@docker ~]# cat /data/index.html mount nginx test
我们是将宿主机的/data目录挂载到容器的/data目录,本地目录的路径必须是绝对路径,如果使用-v参数本地目录不存在Docker会自动创建目录。这样宿主机和Docker的/data目录数据就同步,相当于NFS挂载。
③查看数据卷的yuxl信息
[root@docker ~]# docker inspect demon-nginx #此处省略1万字…… "Mounts": [ { "Type": "bind", "Source": "/data", "Destination": "/data", "Mode": "", "RW": true, "Propagation": "rprivate" } ],