Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

Docker


镜像(Image):

docker镜像好比是一个模板,可以通过这个模板创建容器服务 tomcat镜像==>run==>tomcat01容器(提供服务器)

容器(Contaniner):

Docker利用容器技术,独立运行一个或一个组应用。可以理解位一个简易的linux系统

仓库(Repository):

仓库就是存放容器的地方!分为公有仓库和私有仓库

安装docker (centos7为例)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
## 卸载旧版本
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
## 安装安装包
sudo yum install -y yum-utils
## 设置镜像的仓库 阿里云
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
## 更新yum
yum makecache fast
## 安装docker引擎 -ce社区 -ee企业版
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
## 启动
sudo systemctl start docker
## 查看版本
docker version
## 测试 当容器运行时,它会打印一条确认消息并退出。您现在已经成功安装并启动了 Docker 引擎。
sudo docker run hello-world

卸载docker

1
2
3
sudo yum remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

底层原理

Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上。通过Socket从客户端访问。
Docker-Server接收到Docker-Client的指令,就会执行这个命令!

Docker 常用命令

帮助命令

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

镜像命令

1
2
3
4
docker images 			# 查看本地主机上的镜像
docker search # 搜索镜像
docker pull[:tag] # 下载镜像 不注明tag即最新
docker rmi # 删除镜像

容器命令

下载centos镜像作为测试学习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
docker pull centos
# docker run[可选参数] image
参数说明 --name="Name" 容器名字 用于区分容器
--d 后台运行
--it 交互方式运行 进入容器查看内容
--P 随机指定端口
--p 指定容器端口
docker run -it centos
exit # 停止容器退回主机
docker ps # 所有运行的容器
Ctrl + q + p # 退回主机不停止容器
docker rm 容器id # 删除指定容器
docker rm -rf $(docker ps -aq) #删除所有容器
docker start 容器id
docker restart 容器id
docker stop 容器id
docker kill 容器id # 强制停止

常用其他命令

常见的坑:

  • docker 容器使用后台运行 必须要有一个前台进程
  • nginx,容器启动后,发现没有提供服务,就会立刻停止

查看日志

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

查看镜像源数据

1
docker inspect 容器id

进入当前正在运行的容器

1
2
3
docker exec -it 容器id /bin/bash		#开启新的终端,可以在里面操作
#**OR**#
docker attach 容器id #进入容器正在执行的终端

拷贝容器内的数据至主机

1
docker cp 容器id:路径内路径 目的主机路径

commit镜像

1
2
docker commit		# 提交容器成为一个新的副本
docker commit -m="提交的描述信息" -a="作者" 容器ID 目标镜像名:[TAG]

Docker-Nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
docker pull nginx
docker run -d --name nginx01 -p:3344:80 nginx #3344为linux端口 80为容器端口
curl localhost:3344
======================================
[root@localhost elijah]# curl localhost:3344
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
======================================

Docker-TomCat

1
2
3
4
5
6
7
docker run -d -p 3355:8080 --name tomcat01 tomcat:9.0
curl localhost:3355
======================================
[root@localhost elijah]# curl localhost:3355
## pull至本地的是tomcat最小版本 缺少部署的项目
<!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 404 – Not Found</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Description</b> The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.</p><hr class="line" /><h3>Apache Tomcat/9.0.75</h3></body></html>
======================================

Docker-ES

Elasticsearch 暴露的端口很多!

Elasticsearch 十分得耗内存 1.xG

Elasticsearch 的数据一般需要挂载到安全目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
docker pull docker.elastic.co/elasticsearch/elasticsearch:7.5.2
docker run -p 9200:9200 -p 9300:9300 -d -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:7.5.2
======================================
[root@localhost elijah]# curl localhost:9200
{
"name" : "c876dcd60451",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "QhjzNz7JRiSSRzZqVT_PRw",
"version" : {
"number" : "7.5.2",
"build_flavor" : "default",
"build_type" : "docker",
"build_hash" : "8bec50e1e0ad29dad5653712cf3bb580cd1afcdf",
"build_date" : "2020-01-15T12:11:52.313576Z",
"build_snapshot" : false,
"lucene_version" : "8.3.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
======================================

可视化

portainer

1
2
3
4
5
6
7
8
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

# 测试
curl localhost:8088
<!DOCTYPE html
><html lang="en" ng-app="portainer">

# 外网访问 http://ip:8088

容器数据卷

目的

为了数据持久化和同步操作,将容器内的数据挂载出来 容器与容器也可以数据共享

使用数据卷

1
2
3
4
5
6
# -v
docker run -it -v 主机目录,容器内目录
##测试
docker run -it -v /home/ceshi:/home centos /bin/bash
docker inspect 容器id

Mysql

运行数据库需要数据挂载

1
2
docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql

具名和匿名挂载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# 匿名挂载
-v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx # -P 随机指定端口

# 查看所有volume的情况
docker volume ls
DRIVER VOLUME NAME
local 561b81a03506f31d45ada3f9fb7bd8d7c9b5e0f826c877221a17e45d4c80e096
local 36083fb6ca083005094cbd49572a0bffeec6daadfbc5ce772909bb00be760882

# 这里发现,这种情况就是匿名挂载,我们在-v 后面只写了容器内的路径,没有写容器外的路径!

# 具名挂载
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
26da1ec7d4994c76e80134d24d82403a254a4e1d84ec65d5f286000105c3da17
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
26da1ec7d499 nginx "/docker-entrypoint.…" 3 seconds ago Up 2 seconds 0.0.0.0:32769->80/tcp nginx02
486de1da03cb nginx "/docker-entrypoint.…" 3 minutes ago Up 3 minutes 0.0.0.0:32768->80/tcp nginx01
docker volume ls
DRIVER VOLUME NAME
local 561b81a03506f31d45ada3f9fb7bd8d7c9b5e0f826c877221a17e45d4c80e096
local 36083fb6ca083005094cbd49572a0bffeec6daadfbc5ce772909bb00be760882
local juming-nginx

# 通过-v 卷名:容器内的路径
# 查看一下这个卷
# docker volume inspect juming-nginx

docker volume inspect juming-nginx
[
{
"CreatedAt": "2020-08-12T18:15:21+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
# 所有docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volumes/xxxxx/_data
# 我们通过具名挂载可以方便的找到我们的一个卷,大多数情况下使用的是具名挂载
# 如何确定是具名挂载还是匿名挂载,还是指定路径挂载!
-v 容器内路径 # 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /主机路径:容器内路径 # 指定路径挂载
# 通过 -v 容器内容路径 ro rw 改变读写权限
ro readonly # 只读
rw readwrite # 可读可写

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

# ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内容无法操作

数据卷容器

多个mysql同步数据!

1
2
3
docker run -d -p 3344:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

docker run -d -p 3344:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7

DockerFile

dockerfile 就是用来构建docker镜像的构建文件!

构建步骤

1
2
3
4
>>1.编写一个dockerFile文件
>>2.docker build 构建成为一个镜像
>>3.docker run 运行镜像
>>4.docker push 发布镜像(DockerHub、阿里云镜像)
1
2
3
4
5
6
7
8
9
10
11
mkdir dockerfile
vim dockerfile01
FROM centos
============
VOLUME ["volume01","volume02"]

CMD echo "-----end-----"
CMD /bin/bash
============
docker build -f dockerfile1 -t xiaowo/centos:1.0 .
docker images

指令 # 每行都会提交一个新的镜像层

FROM # 基础镜像,一切从这里开始构建
MAINTAINER # 镜像是谁写的, 姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤, tomcat镜像, 这个tomcat压缩包!添加内容
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 保留端口配置
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效可被替代
ENTRYPOINT # 指定这个容器启动的时候要运行的命令, 可以追加命令
ONBUILD # 当构建一个被继承DockerFile 这个时候就会运行 ONBUILD 的指令,触发指令
COPY # 类似ADD, 将我们文件拷贝到镜像中
ENV # 构建的时候设置环境变量!

实战测试

创建一个自己的centos

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@localhost docker-test-volume]# vim mycentos
[root@localhost docker-test-volume]# cat mycentos
FROM centos:centos7
MAINTAINER XIAOWO<19857178394@163.com>

ENV MYPATH /usr/local
WORKDIR $MYPATH

RUN yum -y install vim
RUN yum -y install net-tools

EXPOSE 80

CMD echo $MYPATH
CMD echo "---end---"
CMD /bin/bash
[root@localhost docker-test-volume]# docker build -f mycentos -t mycentos:0.1 .

Tomcat

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
FROM centos
MAINTAINER xiaowo<19857178394@163.com>

COPY readme.txt /usr/local/readme.txt

ADD jdk-8u73-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.37.tar.gz /usr/local/

RUN yum -y install vim

ENV MYPATH /usr/local
WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk1.8.0_73
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.37
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.37
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

CMD /usr/local/apache-tomcat-9.0.37/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.37/bin/logs/catalina.out

Docker网络

理解docker0

思考一个场景,我们编写了一个微服务,database url =ip; 项目不重启,数据ip换掉了,我们希望可以处理这个问题,可以按名字来进行访问容器

1
2
docker run -d -P  --name tomcat03 --link tomcat02 tomcat
# 3可ping2 2不可ping3

-自定义网络

网络模式
1
2
3
4
5
[root@localhost docker-test-volume]# docker network ls
NETWORK ID NAME DRIVER SCOPE
dda70ac5191c bridge bridge local
00d9897200c1 host host local
34a89431ba8e none null local

bridge 网络模式

在该模式中,Docker 守护进程创建了一个虚拟以太网桥 docker0,新建的容器会自动桥接到这个接口,附加在其上的任何网卡之间都能自动转发数据包。

默认情况下,守护进程会创建一对对等虚拟设备接口 veth pair,将其中一个接口设置为容器的 eth0 接口(容器的网卡),另一个接口放置在宿主机的命名空间中,以类似 vethxxx 这样的名字命名,从而将宿主机上的所有容器都连接到这个内部网络上。

host 网络模式

host 网络模式需要在创建容器时通过参数 --net host 或者 --network host 指定;

采用 host 网络模式的 Docker Container,可以直接使用宿主机的 IP 地址与外界进行通信,若宿主机的 eth0 是一个公有 IP,那么容器也拥有这个公有 IP。同时容器内服务的端口也可以使用宿主机的端口,无需额外进行 NAT 转换;

host 网络模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离性。

none 网络模式

none 网络模式是指禁用网络功能,只有 lo 接口 local 的简写,代表 127.0.0.1,即 localhost 本地环回接口。在创建容器时通过参数 --net none 或者 --network none 指定;

none 网络模式即不为 Docker Container 创建任何的网络环境,容器内部就只能使用 loopback 网络设备,不会再有其他的网络资源。可以说 none 模式为 Docke Container 做了极少的网络设定,但是俗话说得好“少即是多”,在没有网络配置的情况下,作为 Docker 开发者,才能在这基础做其他无限多可能的网络定制开发。这也恰巧体现了 Docker 设计理念的开放。

container 网络模式

  • Container 网络模式是 Docker 中一种较为特别的网络的模式。在创建容器时通过参数 --net container:已运行的容器名称|ID 或者 --network container:已运行的容器名称|ID 指定;
  • 处于这个模式下的 Docker 容器会共享一个网络栈,这样两个容器之间可以使用 localhost 高效快速通信。

Container 网络模式即新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样两个容器除了网络方面相同之外,其他的如文件系统、进程列表等还是隔离的。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 我们直接启动的命令默认有一个 --net bridge,而这个就是我们的docker0
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 --net bridge tomcat

# docker0特点,默认,容器名不能访问, --link可以打通连接!
# 我们可以自定义一个网络!
# --driver bridge
# --subnet 192.168.0.0/16 可以支持255*255个网络 192.168.0.2 ~ 192.168.255.254 65535
# --gateway 192.168.0.1 网关
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
26a5afdf4805d7ee0a660b82244929a4226470d99a179355558dca35a2b983ec
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
30d601788862 bridge bridge local
226019b14d91 host host local
26a5afdf4805 mynet bridge local
7496c014f74b none null local

评论