docker从入门到如土,docker笔记(一篇全)

Docker 镜像都是只读的,当容器启动时,一个新的可写层被加到镜像的顶部。

这一层就是我们通常说的容器层,容器层之下的都叫镜像层

联合文件系统(UnionFS)是 Docker 的核心,也是 Docker 得以极致精简的保证。分层下载

分层镜像的好处,与之前的版本共用一部分,不用再重复下载

基础命令

docker version #查看docker的版本信息

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

docker 命令 --help #帮助命令(可查看可选的参数)

docker COMMAND --help

镜像命令

docker images 查看本地主机的所有镜像

docker search 搜索镜像

docker pull 镜像名[:tag] 下载镜像 指定版本下载

docker rmi 删除镜像

容器命令

docker run [可选参数] image

#参数说明
–name=“名字” 指定容器名字
-d 后台方式运行
-it 使用交互方式运行,进入容器查看内容
-p 指定容器的端口
(
-p ip:主机端口:容器端口 配置主机端口映射到容器端口
-p 主机端口:容器端口
-p 容器端口
)
-P 随机指定端口(大写的P)

exit 停止并退出容器(后台方式运行则仅退出)

Ctrl+P+Q 不停止容器退出

docker ps 列出运行过的容器命令

# 列出当前正在运行的容器 -a

# 列出所有容器的运行记录 -n=?

# 显示最近创建的n个容器 -q

# 只显示容器的编号

docker rm 容器id #删除指定的容器,不能删除正在运行的容器,强制删除使用 rm -f
docker rm -f $(docker ps -aq) #删除所有的容器
docker ps -a -q|xargs docker rm #删除所有的容器

docker start 容器id            #启动容器

docker restart 容器id          #重启容器

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

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

日志的查看

docker logs --help

查看容器中进程信息

docker top

查看容器的元数据

docker inspect 容器id

进入当前正在运行的容器

docker exec -it c703b5b1911f /bin/bash

docker attach c703b5b1911f

拷贝操作

#拷贝容器的文件到主机中

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

#拷贝宿主机的文件到容器中

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

图形化管理工具Portaniner安装

docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

提交镜像

使用docker commit 命令提交容器成为一个新的版本

docker commit -m=“提交的描述信息” -a=“作者” 容器id 目标镜像名:[TAG]

Docker安装Zabbix及可视化界面

先下载镜像 docker pull mysql-server、zabbix-java-gateway、zabbix-server-mysql、zabbix-web-nginx-mysql

启动MySQL实例

docker run --name mysql-server -t
-e MYSQL_DATABASE=“zabbixdb”
-e MYSQL_USER=“zabbix”
-e MYSQL_PASSWORD=“zabbix_paw”
-e MYSQL_ROOT_PASSWORD=“root_user”
-p 3307:3306
-d mysql:8.0
–character-set-server=utf8 --collation-server=utf8_bin
–default-authentication-plugin=mysql_native_password

启动Zabbix Java gateway实例

docker run --name zabbix-java-gateways -t
-d zabbix/zabbix-java-gateway

启动Zabbix server实例

docker run --name zabbix-server-mysqls -t
-e DB_SERVER_HOST=“36.139.53.254”
-e DB_SERVER_PORT=“3307”
-e MYSQL_DATABASE=“zabbixdb”
-e MYSQL_USER=“zabbix”
-e MYSQL_PASSWORD=“zabbix_paw”
-e MYSQL_ROOT_PASSWORD=“root_user”
-e ZBX_JAVAGATEWAY=“zabbix-java-gateways”
-p 10051:10051
-d zabbix/zabbix-server-mysql

启动Zabbix Web界面

docker run --name zabbix-web-nginx-mysqls -t
-e ZBX_SERVER_HOST=“36.139.53.254”
-e DB_SERVER_HOST=“36.139.53.254”
-e DB_SERVER_PORT=“3307”
-e MYSQL_DATABASE=“zabbixdb”
-e MYSQL_USER=“zabbix”
-e MYSQL_PASSWORD=“zabbix_paw”
-e MYSQL_ROOT_PASSWORD=“root_user”
-p 80:8080
-d zabbix/zabbix-web-nginx-mysql

访问

地址: ip:80

默认的用户名 Admin 以及密码 zabbix,即可登录

常用容器部署

Nginx部署

(1)搜索并下载镜像

docker search nginx

docker pull nginx

docker images

docker run -d --name nginx01 -p 3334:80 nginx

-d 后台运行 --name 给容器命名 -p 3334:80 将宿主机的端口3334映射到该容器的80端口

分层镜像

  • bootfs(boot file system):启动文件系统。
  • rootfs:root file system:基础文件系统。

Docker 自定义镜像

docker commit [参数] 容器 [仓库[:标签]]

docker commit -m=“提交的描述信息” -a=“作者” 容器id 目标镜像名:[tag]

  • -a:作者信息。一般为 作者名字<邮箱>
  • -c:将 Dockerfile 指令应用于创建的映像。
  • -m:注释信息。
  • -p:提交期间暂停容器(默认)。

下载Tomcat镜像到本地

docker pull tomcat:9.0

docker images

启动容器

docker run -it --name tomcat123 -p 8888:8080 tomcat:9.0

docker exec -it tomcat123 /bin/bash

对Tomcat镜像进行修改

cp -r webapps.dist/* webapps

ls -l webapps

提交镜像

# 退出Tomcat容器

exit

# 执行docker commit 提交生成新的tomcat镜像

docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]

docker commit -m=“add webapps App” -a=“sunwukong” d60ed0bff852 tomcat123:1.0

启动自定义的Tomcat镜像

docker run -it -p 8888:8080 tomcat123:1.0

Docker 数据存储

目录的挂载,将我们容器内的目录,同步到linux上面,容器间也是可以数据共享的

方式一:直接使用命令来挂载 -v

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

#测试
$ docker run -it -v /home/ceshi:/home centos /bin/bash

#启动后查看挂载情况
$ docker inspect 990046eb50f5

以交互模式启动 centos 镜像

docker run -it -v /home/ceshi:/home centos /bin/bash

Mounts 下的 Source 即为设置的主机目录、Destination 即为设置的容器目录

#测试
docker run -it -v /home/ceshi:/home centos /bin/bash
#启动后查看挂载情况
docker inspect 990046eb50f5

数据卷技术实现的是双向同步

  • ro(readonly):只读。
  • rw(readwrite):可读可写。

实战

#获取镜像
$ docker pull mysql

#运行容器,需要做数据挂载 
#安装启动mysql需要配置密码(注意)
#官方测试:docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

#启动自己的
-d 后台运行
-p 端口映射
-e 环境配置
--name 容器名字

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 mysql101 mysql:5.7

#启动成功之后,在本地用数据库连接工具测试连接(我使用的Navicat Premium)

#sql可视化工具连接到服务器的3310 ---- 3310 和容器内的3306映射,成功连接

#在本地测试创建一个数据库,发现mysql/data 中增加了数据库数据

具名和匿名挂载

具名挂载

由于指定了卷名,所以这种方式称为具名挂载由于指定了卷名,所以这种方式称为具名挂载

启动镜像时只定义主机卷名称,不指定挂载目录。

docker run -it -v my-centos:/home centos /bin/bash

# 使用 Ctrl + P + Q 不退出容器的情况下回到主机目录。

查看目前挂载的卷

docker volume ls

查看卷的详情

[root@sail mysql]# docker volume inspect my-centos
[
{
“CreatedAt”: “2021-12-20T16:55:35+08:00”,
“Driver”: “local”,
“Labels”: null,
“Mountpoint”: “/var/lib/docker/volumes/my-centos/_data”,
“Name”: “my-centos”,
“Options”: null,
“Scope”: “local”
}
]

卷挂载在 /var/lib/docker/volumes/卷名/_data 目录下

匿名挂载

启动镜像时只指定容器目录

docker run -it -v /home centos /bin/bash

查看目前挂载的卷

docker volume ls

查看卷的详情

docker volume inspect

DockerFile的指令

  • 每个指令都必须是大写字母。
  • 按照从上到下顺序执行。
  • # 表示注释。
  • 每一条指令都会创建一个新的镜像层。
FROM            #基础镜像,一切从这里开始
MAINTAINER      #镜像是谁写的,姓名+邮箱
RUN             #镜像构建的时候需要执行的命令
ADD             #添加内容,
WORKDIR         #镜像的工作目录
VOLUME          #卷挂载的目录
EXPOSE          #暴漏端口配置,与docker run -p 宿主机端口:容器内端口 效果一样
CMD             #指定这个容器启动的时候要运行的命令,只有最后一个会生效
ENTRYPOINT      #指令这个容器启动的时候执行的命令 可以追加命令
ONBUILD         #当构建一个被继承的DockerFile时,会运行ONBUILD的指令,触发指令
COPY            #类似于ADD,将我们文件拷贝到镜像中
ENV             #构建的时候设置环境变量
#以上面的 centos 官方镜像的 Dockerfile 为例
#Docker Hub 中 99% 的镜像都是从FROM scratch 开始的。
FROM scratch
ADD centos-7-docker.tar.xz /
LABEL org.label-schema.schema-version="1.0" \
    org.label-schema.name="CentOS Base Image" \
    org.label-schema.vendor="CentOS" \
    org.label-schema.license="GPLv2" \
    org.label-schema.build-date="20181204"
CMD ["/bin/bash"]

docker build

Dockerfile 编写好后,需要使用 docker build 命令运行

docker build [参数] 路径 | 网络地址 | -

docker build -f 路径 -t name:tag

  • -f:指定要使用的Dockerfile路径。
  • -t:镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签。
  • -m:设置内存最大值。

docker history查看构建记录

docker history 镜像

实战

创建包含vim命令的centos镜像

编写 Dockerfile

[root@sail dockerfile]# vim Dockerfile-centos-test 
[root@sail dockerfile]# cat Dockerfile-centos-test 
FROM centos
MAINTAINER sail<[email protected]>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 81
CMD echo $MYPATH
CMD echo "---end---"
CMD ["/bin/bash"]

构建镜像

[root@sail dockerfile]# docker build -f Dockerfile-centos-test -t centos-test .

查看构建的镜像

[root@sail dockerfile]# docker images

查看本地镜像的构建记录

[root@sail dockerfile]# docker history centos-test

运行测试

[root@sail ~]# docker run -it centos-test
[root@530551bc2162 local]# pwd
/usr/local
[root@530551bc2162 local]# vim test.java
[root@530551bc2162 local]#

自定义tomcat环境镜像

编写 Dockerfile

FROM centos
MAINTAINER sail<[email protected]>
COPY readme.txt /usr/local/readme.txt
ENV MYPATH /usr/local/
WORKDIR $MYPATH
ADD jdk-8u301-linux-x64.tar.gz $MYPATH
ADD apache-tomcat-9.0.55.tar.gz $MYPATH
RUN yum -y install vim
ENV JAVA_HOME $MYPATH/jdk1.8.0_301-amd64
ENV CLASSPATH $JAVA_HOME/lib/
ENV CATALINA_HOME $MYPATH/apache-tomcat-9.0.55
ENV CATALINA_BASH $MYPATH/apache-tomcat-9.0.55
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin:$CATALINA_HOME/lib
EXPOSE 8080
CMD $CATALINA_HOME/bin/startup.sh && tail -F $CATALINA_HOME/logs/catalina.out

其中的 readme.txt 一般作为镜像说明文件,可以在里面编写镜像的信息。

构建镜像

[root@sail tomcat]# docker build -t tomcat-test .

启动镜像

[root@sail tomcat]# docker run -d -p 8080:8080 --name sail-tomcat -v 

启动时将 tomcat 的 webappslogs 目录都挂载到了本机

查看挂载目录

[root@sail tomcat]# ls /home/sail/tomcat
logs webapps

进入容器

[root@sail tomcat]# docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED          STATUS          PORTS                    NAMES
9d391e13efdc   tomcat-test   "/bin/sh -c '$CATALI…"   24 minutes ago   Up 24 minutes   0.0.0.0:8080->8080/tcp   sail-tomcat
[root@sail tomcat]# docker exec -it 9d391e13efdc /bin/bash
[root@9d391e13efdc local]# ls
apache-tomcat-9.0.55  bin  etc    games  include    jdk1.8.0_301  lib  lib64  libexec  readme.txt  sbin  share  src
[root@9d391e13efdc local]# cd apache-tomcat-9.0.55/
[root@9d391e13efdc apache-tomcat-9.0.55]# ls
BUILDING.txt  CONTRIBUTING.md  LICENSE    NOTICE    README.md  RELEASE-NOTES  RUNNING.txt  bin  conf  lib  logs  temp  webapps  work

jdk 和 readme.txt 都是具备了的,且 tomcat 目录下的文件也是完整的

查看挂载文件

这里以 logs 为例,我们先进入 tomcat 容器中的 logs 文件夹查看日志内容

[root@9d391e13efdc apache-tomcat-9.0.55]# cd logs
[root@9d391e13efdc logs]# ls
catalina.out
[root@9d391e13efdc logs]# cat catalina.out 
/usr/local//apache-tomcat-9.0.55/bin/catalina.sh: line 504: /usr/local//jdk1.8.0_301-amd64/bin/java: No such file or directory

然后再退出查看主机上挂载的 logs 文件夹

[root@9d391e13efdc logs]# exit
exit
[root@sail tomcat]# cd /home/sail/tomcat/logs
[root@sail logs]# ls
catalina.out
[root@sail logs]# cat catalina.out 
/usr/local//apache-tomcat-9.0.55/bin/catalina.sh: line 504: /usr/local//jdk1.8.0_301-amd64/bin/java: No such file or directory

两个地方 logs 下的文件内容一致,说明挂载成功

发布镜像到 Docker Hub

注册账号

登录 Docker Hub 账号

[root@sail logs]# docker login -u asailing
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded

发布镜像

docker push

[root@sail logs]# docker push centos-test
Using default tag: latest
The push refers to repository [docker.io/library/centos-test]
de70c523870b: Preparing 
909db45c4bc4: Preparing 
74ddd0ec08fa: Preparing 
denied: requested access to the resource is denied

指定镜像标签

docker tag

必须以 账号名/镜像名:标签 的格式命令才能提交

[root@sail logs]# docker tag d58be7785771 asailing/centos:1.0
[root@sail logs]# docker images
REPOSITORY        TAG       IMAGE ID       CREATED        SIZE
asailing/centos   1.0       d58be7785771   29 hours ago   323MB
centos-test       latest    d58be7785771   29 hours ago   323MB

此时会多出一个相同 ID 但是标签和名字不同的镜像

再次发布镜像

[root@sail logs]# docker push asailing/centos:1.0
The push refers to repository [docker.io/asailing/centos]
de70c523870b: Pushed 
909db45c4bc4: Pushed 
74ddd0ec08fa: Pushed 
1.0: digest: sha256:ecefaae6c5a2cab84693175ea3b18d0d0a7aa0160e33a0bf3eb4ab626b10f0f1 size: 953

这样就能发布成功了。且可以发现,镜像的发布也是分层发布的

配置国内镜像站

由于对国外网络的限制,发布镜像到 DockerHub 是比较缓慢的。

这里可以使用配置 Docker 国内镜像站的方式实现加速。

运行以下命令即可:

[root@sail ~]# curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io
docker version >= 1.12
{
  "registry-mirrors": ["http://f1361db2.m.daocloud.io"]
}
Success.
You need to restart docker to take effect: sudo systemctl restart docker
[root@sail ~]# systemctl restart docker
[root@sail ~]#

该脚本可以将 --registry-mirror 加入到 Docker 配置文件 /etc/docker/daemon.json

适用于 Ubuntu14.04DebianCentOS6CentOS7FedoraArch LinuxopenSUSE Leap 42.1,其他版本可能有细微不同

去 Docker Hub 上以 账号名/镜像名 搜索我们刚发布的镜像,发现是可以搜索到的

发布镜像到阿里云镜像仓库

登录阿里云,点击我的阿里云

docker从入门到如土,docker笔记(一篇全)_第1张图片

创建实例

docker从入门到如土,docker笔记(一篇全)_第2张图片

进入镜像仓库

创建好个人实例后,点击进入。

docker从入门到如土,docker笔记(一篇全)_第3张图片

创建命名空间

docker从入门到如土,docker笔记(一篇全)_第4张图片

一个账号只能创建 3 个命名空间,需要谨慎创建。

docker从入门到如土,docker笔记(一篇全)_第5张图片

创建镜像仓库

docker从入门到如土,docker笔记(一篇全)_第6张图片

点击下一步,创建本地仓库

docker从入门到如土,docker笔记(一篇全)_第7张图片docker从入门到如土,docker笔记(一篇全)_第8张图片至此,我们就创建好了阿里云的镜像仓库

退出登录的账号

[root@sail logs]# docker logout
Removing login credentials for https://index.docker.io/v1/

登录阿里云账号

[root@sail logs]# docker login --username=内有千丘外无锋 registry.cn-hangzhou.aliyuncs.com
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded

Linux 网络

有三个网卡信息:

  • lo:本地。
  • ens:虚拟机或阿里云服务器地址。
  • docker0:Docker 网络地址。

Docker 网络

在 Docker 安装后,主机会为 Docker 分配一个网卡,名为 docker0

该网卡使用桥接模式,使用的是 veth-pair 技术

启动两个容器

查看 Linux 网络

[root@sail tomcat]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:16:3e:30:01:20 brd ff:ff:ff:ff:ff:ff
    inet 172.24.19.94/18 brd 172.24.63.255 scope global dynamic eth0
       valid_lft 310199524sec preferred_lft 310199524sec
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:23:ae:ac:24 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
7: veth4a18f1b@if110: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 52:69:3c:bc:83:4a brd ff:ff:ff:ff:ff:ff link-netnsid 0
9: veth296fd0d@if112: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 76:3c:34:e8:c4:90 brd ff:ff:ff:ff:ff:ff link-netnsid 1

Docker 每启动一个容器,就会分配一个 IP

查看容器的内部网络

[root@sail ~]# docker exec -it tomcat01 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

可以看到容器内 IP 与本机 IP 成对出现,这就是 veth-pair 技术

容器访问 docker0 测试

[root@sail ~]# docker exec -it tomcat01 ping 172.17.0.1
PING 172.17.0.1 (172.17.0.1) 56(84) bytes of data.
64 bytes from 172.17.0.1: icmp_seq=1 ttl=64 time=0.845 ms
64 bytes from 172.17.0.1: icmp_seq=2 ttl=64 time=0.139 ms
64 bytes from 172.17.0.1: icmp_seq=3 ttl=64 time=0.130 ms
64 bytes from 172.17.0.1: icmp_seq=4 ttl=64 time=0.134 ms
64 bytes from 172.17.0.1: icmp_seq=5 ttl=64 time=0.119 ms
64 bytes from 172.17.0.1: icmp_seq=6 ttl=64 time=0.082 ms

容器与 docker0 之间是可以访问的

容器与容器之间访问

Docker 中的所有网络接口都是虚拟的,相当于内网传递。

只要删除容器,对应网络就会删除。

容器间网络连接

docker run —link

每次重启容器或 Linux,IP 就会变化,固定 IP 互联网络就会失效。

如果能使用服务名来连接,而不考虑 IP,就会方便很多。

测试使用容器名来 ping

[root@sail ~]# docker exec -it tomcat01 ping tomcat02
ping: tomcat02: Name or service not known

容器之间无法通过容器名来连接

先启动 tomcat01

[root@sail ~]# docker run -d -P --name=tomcat01 tomcat
0d39450a3253544ff5a9bf390b450a218b1055c4d1e60fc02b153ab58544d600

使用 –-link 命令启动 tomcat02

[root@sail ~]# docker run -d -P --name tomcat02 --link tomcat01 tomcat
1901445346baf10ddca6e8a639f0aed72b2cf758046e6da9c28426857c7bb3fd

在 tomcat02 访问 tomcat01

[root@node1 ~]# docker exec -it tomcat02 ping tomcat01
PING tomcat01 (172.17.0.2) 56(84) bytes of data.
64 bytes from tomcat01 (172.17.0.2): icmp_seq=1 ttl=64 time=0.120 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=2 ttl=64 time=0.184 ms
^C
--- tomcat01 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 3ms
rtt min/avg/max/mdev = 0.120/0.152/0.184/0.032 ms

在 tomcat01 访问 tomcat02 则无法访问

tomcat02 能够通过容器名访问 tomcat01,原理是 --link 通过 tomcat02 在自己容器 hosts 文件中配置了 tomcat01 IP 信息

[root@sail ~]# docker exec -it tomcat02 cat /etc/hosts
127.0.0.1    localhost
::1    localhost ip6-localhost ip6-loopback
fe00::0    ip6-localnet
ff00::0    ip6-mcastprefix
ff02::1    ip6-allnodes
ff02::2    ip6-allrouters
172.17.0.2    tomcat01 0d39450a3253
172.17.0.3    1901445346ba

这种方式已经不流行了,建议使用自定义网络实现。

查看Docker网络信息

docker network ls

[root@sail ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
f3eeb014197a   bridge    bridge    local
28d77e958643   host      host      local
c3ff850e96f0   none      null      local
  • bridge:桥接模式(默认)。自己创建也使用这种模式。
  • host:和宿主即共享。
  • none:不配置网络。

创建自定义网络

启动容器

[root@sail ~]# docker run -d -P --net bridge --name tomcat01 tomcat
f048aad0addb07e861c138d167cd644c4c99f9d64c99c6b8ab3f7960fde1dce4

在我们启动容器的时候默认会有一个网络设置

自定义网络,先使用 docker network --help 命令查询一下

[root@sail ~]# docker network --help
Usage:  docker network COMMAND
Manage networks
Commands:
  connect     Connect a container to a network
  create      Create a network
  disconnect  Disconnect a container from a network
  inspect     Display detailed information on one or more networks
  ls          List networks
  prune       Remove all unused networks
  rm          Remove one or more networks
Run 'docker network COMMAND --help' for more information on a command.

docker network create

参数

  • -d:网络模式
  • --subnet:子网
  • --gateway:网关

创建自定义网络

[root@sail ~]# docker network create -d bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
801fbbe1b38c81b12ce90aa9139561b5843dca64b4b17718b6e2622369f9be67

查看创建的网络

[root@sail ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
f3eeb014197a   bridge    bridge    local
28d77e958643   host      host      local
801fbbe1b38c   mynet     bridge    local
c3ff850e96f0   none      null      local
[root@sail ~]# docker network inspect 801fbbe1b38c
[
    {
        "Name": "mynet",
        "Id": "801fbbe1b38c81b12ce90aa9139561b5843dca64b4b17718b6e2622369f9be67",
        "Created": "2021-12-30T17:39:43.100705632+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

以下配置可以看出,自定义网络创建完成

"Config": [
    {
        "Subnet": "192.168.0.0/16",
        "Gateway": "192.168.0.1"
    }
]

启动镜像

[root@sail ~]# docker run -d -P --net=mynet --name=tomcat01 tomcat 
f3fad0c65fc3eb9a39b1189a25f5a7f664a0b9415df05cca5ee6edb6b7cc1915
[root@sail ~]# docker run -d -P --net=mynet --name=tomcat02 tomcat
68a78759663854c6d83a14fcc0cf45515e61c5e81d10799e96b22ef79c0d478f

连接测试

[root@sail ~]# docker exec -it tomcat01 ping tomcat02
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.187 ms
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.147 ms
^C
--- tomcat02 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 4ms
rtt min/avg/max/mdev = 0.147/0.167/0.187/0.020 ms

这种方式可以实现不同集群使用不同的网络,保证集群网络的安全。

如 Redis 集群在 192.160.0.0/16 网段下,MySQL 集群在 192.161.0.0/16 网段下

网络连通

docker network connect

使用docker network connect实现一个容器链接到另一个网段。

建立连接

[root@sail ~]# docker run -d -P --name=tomcat02-net tomcat
5a02cd4172daccc5073907ee6b063560687db5ffdd5041b18fd3ff1055a8984c
[root@sail ~]# docker network connect mynet tomcat02-net
[root@sail ~]#
[root@sail ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
f3eeb014197a   bridge    bridge    local
28d77e958643   host      host      local
801fbbe1b38c   mynet     bridge    local
c3ff850e96f0   none      null      local
[root@sail ~]# docker network inspect 801fbbe1b38c
[
    {
        "Name": "mynet",
        "Id": "801fbbe1b38c81b12ce90aa9139561b5843dca64b4b17718b6e2622369f9be67",
        "Created": "2021-12-30T17:39:43.100705632+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "5a02cd4172daccc5073907ee6b063560687db5ffdd5041b18fd3ff1055a8984c": {
                "Name": "tomcat02-net",
                "EndpointID": "e6503138bcb91a7693576e324df75d1dff594f1c5aa3e08397802c38133eb0e9",
                "MacAddress": "02:42:c0:a8:00:05",
                "IPv4Address": "192.168.0.5/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

查看容器详情

[root@sail ~]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED             STATUS             PORTS                     NAMES
5a02cd4172da   tomcat    "catalina.sh run"   5 minutes ago       Up 5 minutes       0.0.0.0:49159->8080/tcp   tomcat02-net
[root@sail ~]# docker inspect 5a02cd4172da

这里也可以发现容器 tomcat02-net 已经与 mynet 建立了连接

测试连接

[root@sail ~]# docker exec -it tomcat02 ping tomcat02-net
PING tomcat02-net (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat02-net.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.121 ms
64 bytes from tomcat02-net.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.064 ms
^C
--- tomcat02-net ping statistics ---

网络连通成功

Docker Compose

使用 Docker 的时候,定义 Dockerfile 文件,然后使用 docker builddocker run 等命令操作容器。

然而微服务架构的应用系统一般包含若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动启停,这样效率很低,也不方便管理。

使用 Docker Compose 可以轻松、高效的管理容器,它是一个用于定义和运行多容器 Docker 的应用程序工具。

yaml 官方示例

https://docs.docker.com/compose/compose-file/compose-file-v3/#compose-file-structure-and-examples

version: "3.9"
services:
  redis:
    image: redis:alpine
    ports:
      - "6379"
    networks:
      - frontend
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure
  db:
    image: postgres:9.4
    volumes:
      - db-data:/var/lib/postgresql/data
    networks:
      - backend
    deploy:
      placement:
        max_replicas_per_node: 1
        constraints:
          - "node.role==manager"
  vote:
    image: dockersamples/examplevotingapp_vote:before
    ports:
      - "5000:80"
    networks:
      - frontend
    depends_on:
      - redis
    deploy:
      replicas: 2
      update_config:
        parallelism: 2
      restart_policy:
        condition: on-failure
  result:
    image: dockersamples/examplevotingapp_result:before
    ports:
      - "5001:80"
    networks:
      - backend
    depends_on:
      - db
    deploy:
      replicas: 1
      update_config:
        parallelism: 2
        delay: 10s
      restart_policy:
        condition: on-failure
  worker:
    image: dockersamples/examplevotingapp_worker
    networks:
      - frontend
      - backend
    deploy:
      mode: replicated
      replicas: 1
      labels: [APP=VOTING]
      restart_policy:
        condition: on-failure
        delay: 10s
        max_attempts: 3
        window: 120s
      placement:
        constraints:
          - "node.role==manager"
  visualizer:
    image: dockersamples/visualizer:stable
    ports:
      - "8080:8080"
    stop_grace_period: 1m30s
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      placement:
        constraints:
          - "node.role==manager"
networks:
  frontend:
  backend:
volumes:
  db-data:

depends_on:依赖关系,如 web 依赖 redis 和 db,通过 depends_on 表明关系。

version: "3.9"
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

安装

Docker Compose 是 Docker 的一个开源项目,目前托管到了 GitHub,需要前往 GitHub 下载。

sudo curl -L "https://github.com/docker/compose/releases/download/2.2.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

由于存放在 GitHub,国内网络限制导致不太稳定,不推荐使用。

推荐使用 道客 提供的 Docker 极速下载 进行安装。

curl -L https://get.daocloud.io/docker/compose/releases/download/v2.2.3/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

安装

[root@sail ~]# curl -L https://get.daocloud.io/docker/compose/releases/download/v2.2.3/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   423  100   423    0     0    394      0  0:00:01  0:00:01 --:--:--   394
100 23.5M  100 23.5M    0     0  8670k      0  0:00:02  0:00:02 --:--:-- 20.3M
[root@sail ~]# cd /usr/local/bin/
[root@sail bin]# ls
docker-compose

授权

[root@sail ~]# chmod +x /usr/local/bin/docker-compose
[root@sail ~]#

查看版本

docker-compose version

[root@sail bin]# docker-compose version
Docker Compose version v2.2.3

卸载

rm /usr/local/bin/docker-compose

由于 Linux 一切皆文件,删除此文件夹即可完成 Docker Compose 的卸载。

使用

构建

创建项目目录

[root@sail sail]# mkdir docker-compose
[root@sail sail]# cd docker-compose
[root@sail docker-compose]#

创建 app.py

[root@sail docker-compose]# vim app.py
import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)
@app.route('/')
def hello():
    count = get_hit_count()
    return 'Hello World! I have been seen {} times.\n'.format(count)

redis 是应用容器中 redis 容器的主机名,在同一网络下可以通过服务名访问,端口默认 6379。

创建 requirements.txt

[root@sail docker-compose]# vim requirements.txt
[root@sail docker-compose]# cat requirements.txt 
flask
redis

创建 Dockerfile

[root@sail docker-compose]# vim Dockerfile
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]

创建 docker-compose.yml

[root@sail docker-compose]# vim docker-compose.yml
version: "3.3"
services:
  web:
    build: .
    ports:
      - "5000:5000"
  redis:
    image: "redis:alpine"

启动

docker-compose up

运行应用

在项目目录中,运行 docker-compose up 来启动应用程序。

第一次启动需要安装很多环境,比较缓慢。

[root@sail docker-compose]# docker-compose up
[+] Running 7/7
 ⠿ redis Pulled                                                                                                                                                                                              14.1s
   ⠿ 59bf1c3509f3 Pull complete                                                                                                                                                                               3.0s
   ⠿ 719adce26c52 Pull complete                                                                                                                                                                               3.1s
   ⠿ b8f35e378c31 Pull complete                                                                                                                                                                               3.3s
   ⠿ d034517f789c Pull complete                                                                                                                                                                               9.0s
   ⠿ 3772d4d76753 Pull complete                                                                                                                                                                               9.0s
   ⠿ 211a7f52febb Pull complete                                                                                                                                                                               9.1s
Sending build context to Docker daemon     725B
Step 1/10 : FROM python:3.7-alpine
3.7-alpine: Pulling from library/python
59bf1c3509f3: Already exists 
8786870f2876: Pull complete 
45d4696938d0: Pull complete 
ef84af58b2c5: Pull complete 
c3c9b71b9a69: Pull complete 
Digest: sha256:d64e0124674d64e78cc9d7378a1130499ced66a7a00db0521d0120a2e88ac9e4
Status: Downloaded newer image for python:3.7-alpine
 ---> a1034fd13493
Step 2/10 : WORKDIR /code
 ---> Running in e23e4b173abf
Removing intermediate container e23e4b173abf
 ---> 41eb64157cfc
Step 3/10 : ENV FLASK_APP=app.py
 ---> Running in cdefb769398d
Removing intermediate container cdefb769398d
 ---> ab741ac5cb17
Step 4/10 : ENV FLASK_RUN_HOST=0.0.0.0
 ---> Running in 4976c1da428c
Removing intermediate container 4976c1da428c
 ---> 5a5c24d67db6
Step 5/10 : RUN apk add --no-cache gcc musl-dev linux-headers
 ---> Running in 53043bd38e33
fetch https://dl-cdn.alpinelinux.org/alpine/v3.15/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.15/community/x86_64/APKINDEX.tar.gz
(1/13) Installing libgcc (10.3.1_git20211027-r0)
(2/13) Installing libstdc++ (10.3.1_git20211027-r0)
(3/13) Installing binutils (2.37-r3)
(4/13) Installing libgomp (10.3.1_git20211027-r0)
(5/13) Installing libatomic (10.3.1_git20211027-r0)
(6/13) Installing libgphobos (10.3.1_git20211027-r0)
(7/13) Installing gmp (6.2.1-r0)
(8/13) Installing isl22 (0.22-r0)
(9/13) Installing mpfr4 (4.1.0-r0)
(10/13) Installing mpc1 (1.2.1-r0)
(11/13) Installing gcc (10.3.1_git20211027-r0)
(12/13) Installing linux-headers (5.10.41-r0)
(13/13) Installing musl-dev (1.2.2-r7)
Executing busybox-1.34.1-r3.trigger
OK: 139 MiB in 48 packages
Removing intermediate container 53043bd38e33
 ---> 73e9550df596
Step 6/10 : COPY requirements.txt requirements.txt
 ---> c5a73d6f1fe1
Step 7/10 : RUN pip install -r requirements.txt
 ---> Running in 826790d0bfbb
Collecting flask
  Downloading Flask-2.0.2-py3-none-any.whl (95 kB)
Collecting redis
  Downloading redis-4.1.0-py3-none-any.whl (171 kB)
Collecting itsdangerous>=2.0
  Downloading itsdangerous-2.0.1-py3-none-any.whl (18 kB)
Collecting click>=7.1.2
  Downloading click-8.0.3-py3-none-any.whl (97 kB)
Collecting Werkzeug>=2.0
  Downloading Werkzeug-2.0.2-py3-none-any.whl (288 kB)
Collecting Jinja2>=3.0
  Downloading Jinja2-3.0.3-py3-none-any.whl (133 kB)
Collecting packaging>=21.3
  Downloading packaging-21.3-py3-none-any.whl (40 kB)
Collecting deprecated>=1.2.3
  Downloading Deprecated-1.2.13-py2.py3-none-any.whl (9.6 kB)
Collecting importlib-metadata>=1.0
  Downloading importlib_metadata-4.10.0-py3-none-any.whl (17 kB)
Collecting wrapt<2,>=1.10
  Downloading wrapt-1.13.3-cp37-cp37m-musllinux_1_1_x86_64.whl (78 kB)
Collecting zipp>=0.5
  Downloading zipp-3.7.0-py3-none-any.whl (5.3 kB)
Collecting typing-extensions>=3.6.4
  Downloading typing_extensions-4.0.1-py3-none-any.whl (22 kB)
Collecting MarkupSafe>=2.0
  Downloading MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl (30 kB)
Collecting pyparsing!=3.0.5,>=2.0.2
  Downloading pyparsing-3.0.6-py3-none-any.whl (97 kB)
Installing collected packages: zipp, typing-extensions, wrapt, pyparsing, MarkupSafe, importlib-metadata, Werkzeug, packaging, Jinja2, itsdangerous, deprecated, click, redis, flask
Successfully installed Jinja2-3.0.3 MarkupSafe-2.0.1 Werkzeug-2.0.2 click-8.0.3 deprecated-1.2.13 flask-2.0.2 importlib-metadata-4.10.0 itsdangerous-2.0.1 packaging-21.3 pyparsing-3.0.6 redis-4.1.0 typing-extensions-4.0.1 wrapt-1.13.3 zipp-3.7.0
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
WARNING: You are using pip version 21.2.4; however, version 21.3.1 is available.
You should consider upgrading via the '/usr/local/bin/python -m pip install --upgrade pip' command.
Removing intermediate container 826790d0bfbb
 ---> c1483947fad2
Step 8/10 : EXPOSE 5000
 ---> Running in cd59e0408b47
Removing intermediate container cd59e0408b47
 ---> 05c632dea80d
Step 9/10 : COPY . .
 ---> 8c89b910e366
Step 10/10 : CMD ["flask", "run"]
 ---> Running in 1d9d071fee96
Removing intermediate container 1d9d071fee96
 ---> de4639486b50
Successfully built de4639486b50
Successfully tagged docker-compose_web:latest
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
[+] Running 3/3
 ⠿ Network docker-compose_default    Created                                                                                                                                                                  0.3s
 ⠿ Container docker-compose-redis-1  Created                                                                                                                                                                  0.0s
 ⠿ Container docker-compose-web-1    Created                                                                                                                                                                  0.0s
Attaching to docker-compose-redis-1, docker-compose-web-1
docker-compose-redis-1  | 1:C 07 Jan 2022 08:36:26.687 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
docker-compose-redis-1  | 1:C 07 Jan 2022 08:36:26.687 # Redis version=6.2.6, bits=64, commit=00000000, modified=0, pid=1, just started
docker-compose-redis-1  | 1:C 07 Jan 2022 08:36:26.687 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
docker-compose-redis-1  | 1:M 07 Jan 2022 08:36:26.687 * monotonic clock: POSIX clock_gettime
docker-compose-redis-1  | 1:M 07 Jan 2022 08:36:26.688 * Running mode=standalone, port=6379.
docker-compose-redis-1  | 1:M 07 Jan 2022 08:36:26.688 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
docker-compose-redis-1  | 1:M 07 Jan 2022 08:36:26.688 # Server initialized
docker-compose-redis-1  | 1:M 07 Jan 2022 08:36:26.688 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
docker-compose-redis-1  | 1:M 07 Jan 2022 08:36:26.688 * Ready to accept connections
docker-compose-web-1    |  * Serving Flask app 'app.py' (lazy loading)
docker-compose-web-1    |  * Environment: production
docker-compose-web-1    |    WARNING: This is a development server. Do not use it in a production deployment.
docker-compose-web-1    |    Use a production WSGI server instead.
docker-compose-web-1    |  * Debug mode: off
docker-compose-web-1    |  * Running on all addresses.
docker-compose-web-1    |    WARNING: This is a development server. Do not use it in a production deployment.
docker-compose-web-1    |  * Running on http://172.18.0.2:5000/ (Press CTRL+C to quit)

查看镜像

[root@sail docker-compose]# docker images
REPOSITORY           TAG          IMAGE ID       CREATED          SIZE
docker-compose_web   latest       6df8b78250a1   44 seconds ago   185MB
redis                alpine       3900abf41552   5 weeks ago      32.4MB
python               3.7-alpine   a1034fd13493   5 weeks ago      41.8MB

启动 Docker Compose 时,会自动拉取需要的镜像。

查看容器

[root@sail docker-compose]# docker psCONTAINER ID   IMAGE                COMMAND                  CREATED         STATUS         PORTS                    NAMES78a6f8b03a49   docker-compose_web   "flask run"              8 minutes ago   Up 8 minutes   0.0.0.0:5000->5000/tcp   docker-compose-web-1b4da6da4364f   redis:alpine         "docker-entrypoint.s…"   8 minutes ago   Up 8 minutes   6379/tcp                 docker-compose-redis-1

可以看到容器命名都带有数字,是因为需要集群管理,数字代表副本序号。

查看网络

[root@sail docker-compose]# docker network lsNETWORK ID     NAME                     DRIVER    SCOPEb89f719e94e0   bridge                   bridge    local619a5845a105   docker-compose_default   bridge    local28d77e958643   host                     host      local801fbbe1b38c   mynet                    bridge    localc3ff850e96f0   none                     null      local

项目中的内容都在同个网络下。

访问测试

[root@sail docker-compose]# curl localhost:5000Hello World! I have been seen 1 times.[root@sail docker-compose]# curl localhost:5000Hello World! I have been seen 2 times.[root@sail docker-compose]# curl localhost:5000Hello World! I have been seen 3 times.

Docker Compose 启动完成。

停止

docker-compose stop

示例

[root@sail docker-compose]# docker-compose stop[+] Running 2/2 ⠿ Container docker-compose-redis-1  Stopped                                                                                                                    0.2s ⠿ Container docker-compose-web-1    Stopped

停止并删除容器和网络

docker-compose down

示例

[root@sail docker-compose]# docker-compose down[+] Running 3/3 ⠿ Container docker-compose-web-1    Removed                                                                                                                              10.2s ⠿ Container docker-compose-redis-1  Removed                                                                                                                               0.2s ⠿ Network docker-compose_default    Removed
[root@sail docker-compose]# docker psCONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
[root@sail docker-compose]# docker network lsNETWORK ID     NAME      DRIVER    SCOPEb89f719e94e0   bridge    bridge    local28d77e958643   host      host      local801fbbe1b38c   mynet     bridge    localc3ff850e96f0   none      null      local

可以看出,容器网络都被删除了。

你可能感兴趣的:(运维,操作系统,docker,容器,运维)