dockerFile

1. Dockerfile介绍

Dockerfile是一种能够被Docker程序解释的剧本。Dockerfile由一条一条的指令组成,并且有自己的书写格式和支持的命令。当我们需要在容器镜像中指定自己额外的需求时,只需在Dockerfile上添加或修改指令,然后通过docker build生成我们自定义的容器镜像(image)
clip_image002-1644469873598.jpg

2. Dockerfile指令

构建指令

  • 用于构建Image
  • 其指定的操作不会在运行image容器上执行(FROM、MAINTAINER、RUN、ENV、ADD、COPY)

    设置类指令

  • 用于设置image的属性

  • 其指定的操作将在运行image的容器中执行(CMD、ENTRYPOINT、USER 、EXPOSE、VOLUME、WORKDIR、ONBUILD)

    指令说明

    | 指令 | 描述 | | —- | —- | | FROM | 构建新镜像基于的基础镜像 | | LABEL | 标签 | | RUN | 构建镜像时运行的Shell命令 | | COPY | 拷贝文件或目录到镜像中 | | ADD | 解压压缩包并拷贝 | | ENV | 设置环境变量 | | USER | 为RUN、CMD和ENTRYPOINT执行命令指定运行用户 | | EXPOSE | 声明容器运行的服务端口 | | WORKDIR | 为RUN、CMD、ENTRYPOINT、COPY和ADD设置工作目录 | | CMD | 运行容器时默认执行,如果有多个CMD指令,最后一个生效 |

指令详细解释

1, FROM
FROM指令用于指定其后构建新镜像所使用的基础镜像。
FROM指令必是Dockerfile文件中的首条命令。
FROM指令指定的基础image可以是官方远程仓库中的,也可以位于本地仓库,优先本地仓库。
格式:FROM Dockerfile 文件和网络通信原理 以及 容器数据持久化存储机制 - 图2:
例:FROM centos:latest
2, RUN
RUN指令用于在构建镜像中执行命令,有以下两种格式:

  • shell格式

格式:RUN <命令>
例:RUN echo ‘kubemsb’ > /var/www/html/index.html

  • exec格式

格式:RUN [“可执行文件”, “参数1”, “参数2”]
例:RUN [“/bin/bash”, “-c”, “echo kubemsb > /var/www/html/index.html”]
注意: 按优化的角度来讲:当有多条要执行的命令,不要使用多条RUN,尽量使用&&符号与\符号连接成一行。因为多条RUN命令会让镜像建立多层(总之就是会变得臃肿了😃)。
RUN yum install httpd httpd-devel -y
RUN echo test > /var/www/html/index.html
可以改成
RUN yum install httpd httpd-devel -y && echo test > /var/www/html/index.html
或者改成
RUN yum install httpd httpd-devel -y \
&& echo test > /var/www/html/index.html
3, CMD
CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
格式有三种:
CMD [“executable”,”param1”,”param2”]
CMD [“param1”,”param2”]
CMD command param1 param2
每个Dockerfile只能有一条CMD命令。如果指定了多条命令,只有最后一条会被执行。
如果用户启动容器时候指定了运行的命令,则会覆盖掉CMD指定的命令。
什么是启动容器时指定运行的命令?
# docker run -d -p 80:80 镜像名 运行的命令
4, EXPOSE
EXPOSE指令用于指定容器在运行时监听的端口
格式:EXPOSE […]
例:EXPOSE 80 3306 8080
上述运行的端口还需要使用docker run运行容器时通过-p参数映射到宿主机的端口.
5, ENV
ENV指令用于指定一个环境变量.
格式:ENV 或者 ENV =
例:ENV JAVA_HOME /usr/local/jdkxxxx/
6, ADD
ADD指令用于把宿主机上的文件拷贝到镜像中
格式:ADD
可以是一个本地文件或本地压缩文件,还可以是一个url,
如果把写成一个url,那么ADD就类似于wget命令
路径的填写可以是容器内的绝对路径,也可以是相对于工作目录的相对路径
7, COPY
COPY指令与ADD指令类似,但COPY的源文件只能是本地文件
格式:COPY
8, ENTRYPOINT
ENTRYPOINT与CMD非常类似
相同点:一个Dockerfile只写一条,如果写了多条,那么只有最后一条生效都是容器启动时才运行
不同点:如果用户启动容器时候指定了运行的命令,ENTRYPOINT不会被运行的命令覆盖,而CMD则会被覆盖
格式有两种:
ENTRYPOINT [“executable”, “param1”, “param2”]
ENTRYPOINT command param1 param2
9, VOLUME
VOLUME指令用于把宿主机里的目录与容器里的目录映射.
只指定挂载点,docker宿主机映射的目录为自动生成的。
格式:VOLUME [““]
10, USER
USER指令设置启动容器的用户(像hadoop需要hadoop用户操作,oracle需要oracle用户操作),可以是用户名或UID
USER daemon
USER 1001
注意:如果设置了容器以daemon用户去运行,那么RUN,CMD和ENTRYPOINT都会以这个用户去运行镜像构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖所指定的用户
11, WORKDIR
WORKDIR指令设置工作目录,类似于cd命令。不建议使用RUN cd /root ,建议使用WORKDIR
WORKDIR /root

3.Dockerfile基本构成

  • 基础镜像信息
  • 维护者信息
  • 镜像操作指令
  • 容器启动时执行指令

    4. Dockerfile生成容器镜像方法

    clip_image002-1644470109096.jpg

    4. Dockerfile生成容器镜像案例

    4.1 使用Dockerfile生成容器镜像步骤

    ```shell 第一步:创建一个文件夹(目录)

第二步:在文件夹(目录)中创建Dockerfile文件(并编写)及其它文件

第三步:使用docker build命令构建镜像

第四步:使用构建的镜像启动容器

  1. <a name="xIuzw"></a>
  2. #### 4.2 使用Dockerfile生成Nginx容器镜像
  3. ```shell
  4. mkdir -p /opt/dockerfile/nginx
  5. cd /opt/dockerfile/nginx
  6. ## 创建index.html
  7. echo "nginx's running" >> index.html
  8. vim Dockefile
  9. ## 文件内容如下
  10. FROM centos:centos7
  11. MAINTAINER "<776172520@qq.com>"
  12. RUN yum -y install wget
  13. RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
  14. RUN yum -y install nginx
  15. ADD index.html /usr/share/nginx/html/
  16. RUN echo "daemon off;" >> /etc/nginx/nginx.conf
  17. EXPOSE 80
  18. CMD /usr/sbin/nginx
  19. ## 执行build命令
  20. docker build -t centos7-nginx:v1 .
  21. ## 文件输出
  22. Step 1/9 : FROM centos:centos7
  23. ---> eeb6ee3f44bd
  24. Step 2/9 : MAINTAINER "<776172520@qq.com>"
  25. ---> Using cache
  26. ---> 8f605a9e3abc
  27. Step 3/9 : RUN yum -y install wget
  28. ---> Using cache
  29. ---> da91c1029113
  30. Step 4/9 : RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
  31. ---> Using cache
  32. ---> 9c47cc585081
  33. Step 5/9 : RUN yum -y install nginx
  34. ---> Using cache
  35. ---> b6a4c6183cae
  36. Step 6/9 : ADD index.html /usr/share/nginx/html/
  37. ---> 5287d59afcf3
  38. Step 7/9 : RUN echo "daemon off;" >> /etc/nginx/nginx.conf
  39. ---> Running in 5e9121f07f9c
  40. Removing intermediate container 5e9121f07f9c
  41. ---> a49f3a0025b0
  42. Step 8/9 : EXPOSE 80
  43. ---> Running in 61ac268cf8e5
  44. Removing intermediate container 61ac268cf8e5
  45. ---> e489c2c5ca81
  46. Step 9/9 : CMD /usr/sbin/nginx
  47. ---> Running in 2fd98c75d529
  48. Removing intermediate container 2fd98c75d529
  49. ---> 54e4e2b908d9
  50. Successfully built 54e4e2b908d9
  51. Successfully tagged centos7-nginx:v1
  52. ## 启动容器
  53. docker run -d -p 8082:80 centos7-nginx:v1

浏览器访问 http://10.0.0.10:8082

4.3使用dockerfile生成tomcat容器

  1. mkdir -p /opt/dockerfile/tomcat
  2. cd /opt/dockerfile/tomcat
  3. ## 创建index.html
  4. echo "tomcat's running" >> index.html
  5. vim Dockefile
  6. ## dockerfile内容
  7. FROM centos:centos7
  8. MAINTAINER "<776172520@qq.com>"
  9. ENV VERSION=8.5.79
  10. ENV JAVA_HOME=/usr/local/jdk
  11. ENV TOMCAT_HOME=/usr/local/tomcat
  12. RUN yum -y install wget
  13. RUN wget https://dlcdn.apache.org/tomcat/tomcat-8/v${VERSION}/bin/apache-tomcat-${VERSION}.tar.gz
  14. RUN tar xf apache-tomcat-${VERSION}.tar.gz
  15. RUN mv apache-tomcat-${VERSION} /usr/local/tomcat
  16. RUN rm -rf apache-tomcat-${VERSION}.tar.gz /usr/local/tomcat/webapps/*
  17. RUN mkdir /usr/local/tomcat/webapps/ROOT
  18. ADD ./index.html /usr/local/tomcat/webapps/ROOT/
  19. ADD ./jdk /usr/local/jdk
  20. RUN echo "export TOMCAT_HOME=/usr/local/tomcat" >> /etc/profile
  21. RUN echo "export JAVA_HOME=/usr/local/jdk" >> /etc/profile
  22. RUN echo "export PATH=${TOMCAT_HOME}/bin:${JAVA_HOME}/bin:$PATH" >> /etc/profile
  23. RUN echo "export CLASSPATH=.:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar" >> /etc/profile
  24. RUN source /etc/profile
  25. EXPOSE 8080
  26. CMD ["/usr/local/tomcat/bin/catalina.sh","run"]
  27. ## 创建镜像
  28. docker build -t centos-tomcat:v1 .
  29. docker images
  30. ## 启动镜像
  31. docker run -d -p 8083:8080 centos-tomcat:v1

浏览器访问 http://10.0.0.10:8083

5.使用Dockerfile生成容器镜像优化

5.1减少镜像分层

Dockerfile中包含多种指令,如果涉及到部署最多使用的算是RUN命令了,使用RUN命令时,不建议每次安装都使用一条单独的RUN命令,可以把能够合并安装指令合并为一条,这样就可以减少镜像分层。

  1. FROM centos:latest
  2. MAINTAINER www.kubemsb.com
  3. RUN yum install epel-release -y
  4. RUN yum install -y gcc gcc-c++ make -y
  5. RUN wget http://docs.php.net/distributions/php-5.6.36.tar.gz
  6. RUN tar zxf php-5.6.36.tar.gz
  7. RUN cd php-5.6.36
  8. RUN ./configure --prefix=/usr/local/php
  9. RUN make -j 4
  10. RUN make install
  11. EXPOSE 9000
  12. CMD ["php-fpm"]

优化后

  1. FROM centos:latest
  2. MAINTAINER www.kubemsb.com
  3. RUN yum install epel-release -y && \
  4. yum install -y gcc gcc-c++ make
  5. RUN wget http://docs.php.net/distributions/php-5.6.36.tar.gz && \
  6. tar zxf php-5.6.36.tar.gz && \
  7. cd php-5.6.36 && \
  8. ./configure --prefix=/usr/local/php && \
  9. make -j 4 && make install
  10. EXPOSE 9000
  11. CMD ["php-fpm"]

5.2 清理无用数据

  • 一次RUN形成新的一层,如果没有在同一层删除,无论文件是否最后删除,都会带到下一层,所以要在每一层清理对应的残留数据,减小镜像大小。
  • 把生成容器镜像过程中部署的应用软件包做删除处理 ```shell FROM centos:latest MAINTAINER www.kubemsb.com RUN yum install epel-release -y && \ yum install -y gcc gcc-c++ make gd-devel libxml2-devel \ libcurl-devel libjpeg-devel libpng-devel openssl-devel \ libmcrypt-devel libxslt-devel libtidy-devel autoconf \ iproute net-tools telnet wget curl && \ yum clean all && \ rm -rf /var/cache/yum/*

RUN wget http://docs.php.net/distributions/php-5.6.36.tar.gz && \ tar zxf php-5.6.36.tar.gz && \ cd php-5.6.36 && \ ./configure —prefix=/usr/local/php \ make -j 4 && make install && \ cd / && rm -rf php*

  1. <a name="hXMc3"></a>
  2. #### 5.2 多阶段构建镜像
  3. 项目容器镜像有两种,一种直接把项目代码复制到容器镜像中,下次使用容器镜像时即可直接启动;另一种把需要对项目源码进行编译,再复制到容器镜像中使用。<br />不论是哪种方法都会让制作镜像复杂了些,并也会让容器镜像比较大,建议采用分阶段构建镜像的方法实现。
  4. ```shell
  5. $ git clone https://github.com/kubemsb/tomcat-java-demo
  6. $ cd tomcat-java-demo
  7. $ vi Dockerfile
  8. FROM maven AS build
  9. ADD ./pom.xml pom.xml
  10. ADD ./src src/
  11. RUN mvn clean package
  12. FROM kubemsb/tomcat
  13. RUN rm -rf /usr/local/tomcat/webapps/ROOT
  14. COPY --from=build target/*.war /usr/local/tomcat/webapps/ROOT.war
  15. $ docker build -t demo:v1 .
  16. $ docker container run -d -v demo:v1
  1. 第一个 FROM 后边多了个 AS 关键字,可以给这个阶段起个名字
  2. 第二个 FROM 使用上面构建的 Tomcat 镜像,COPY 关键字增加了 from 参数,用于拷贝某个阶段的文件到当前阶段。

网络与通信原理

2.1 容器默认网络模型

image-20220208180516669.png

  • docker0
    • 是一个二层网络设备,即网桥
    • 通过网桥可以将Linux支持的不同的端口连接起来
    • 实现类交换机多对多的通信
  • veth pair
    • 虚拟以太网(Ethernet)设备
    • 成对出现,用于解决网络命名空间之间的隔离
    • 一端连接Container network namespace,另一端连接host network namespace

      2.2 Docker容器默认网络模型工作原理

      容器访问外网

image-20220208190823162.png

  1. docker run -d --name web1 -p 8085:80 nginx:latest
  2. iptables -t nat -vnL POSTROUTING
  3. #输出
  4. Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
  5. pkts bytes target prot opt in out source destination
  6. 0 0 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0
  7. 0 0 MASQUERADE tcp -- * * 172.17.0.2 172.17.0.2 tcp dpt:80

外网容器访问

image-20220208191400324.png

  1. iptables -t nat -vnL DOCKER
  2. #输出
  3. Chain DOCKER (2 references)
  4. pkts bytes target prot opt in out source destination
  5. 0 0 RETURN all -- docker0 * 0.0.0.0/0 0.0.0.0/0
  6. 0 0 DNAT tcp -- !docker0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8085 to:172.17.0.2:80

2.3 Docker容器四种网络模型

image-20220209120452509.png

查看已有的网络

  1. docker network ls
  2. ## 输出
  3. NETWORK ID NAME DRIVER SCOPE
  4. 6918e664b646 bridge bridge local
  5. 724b9c2a701c host host local
  6. 968a94b5a0b7 none null local
  7. #查看已有网络模型详细信息
  8. [root@localhost tomcat]# docker network inspect bridge
  9. [
  10. {
  11. "Name": "bridge",
  12. "Id": "6918e664b646b83122307fd6ca625ef8956bb6e6c099e07e16ea7cdaa99b1edc",
  13. "Created": "2022-06-12T05:13:21.215256676-04:00",
  14. "Scope": "local",
  15. "Driver": "bridge",
  16. "EnableIPv6": false,
  17. "IPAM": {
  18. "Driver": "default",
  19. "Options": null,
  20. "Config": [
  21. {
  22. "Subnet": "172.17.0.0/16",
  23. "Gateway": "172.17.0.1"
  24. }
  25. ]
  26. },
  27. "Internal": false,
  28. "Attachable": false,
  29. "Ingress": false,
  30. "ConfigFrom": {
  31. "Network": ""
  32. },
  33. "ConfigOnly": false,
  34. "Containers": {
  35. "e50d5675f757b6a1f16aaaafb9c1ec1c3590ad0084c81ae96dbdd2d9cf6be370": {
  36. "Name": "web1",
  37. "EndpointID": "3f190a13701ec8382d47188f4b4f471ae527d316b5d625d372610aa79440a832",
  38. "MacAddress": "02:42:ac:11:00:02",
  39. "IPv4Address": "172.17.0.2/16",
  40. "IPv6Address": ""
  41. }
  42. },
  43. "Options": {
  44. "com.docker.network.bridge.default_bridge": "true",
  45. "com.docker.network.bridge.enable_icc": "true",
  46. "com.docker.network.bridge.enable_ip_masquerade": "true",
  47. "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
  48. "com.docker.network.bridge.name": "docker0",
  49. "com.docker.network.driver.mtu": "1500"
  50. },
  51. "Labels": {}
  52. }
  53. ]
  54. 查看docker支持的网络模型
  55. # docker info | grep Network
  56. Network: bridge host ipvlan macvlan null overlay


创建指定类型的网络模型

bridge
  1. #创建一个名称为mybr0的网络
  2. docker network create -d bridge --subnet "192.168.100.0/24" --gateway "192.168.100.1" -o com.docker.network.bridge.name=docker1 mybr0
  3. #查看已创建网络
  4. docker network ls
  5. ## 查看
  6. NETWORK ID NAME DRIVER SCOPE
  7. 6918e664b646 bridge bridge local
  8. 724b9c2a701c host host local
  9. 6c949f0e4671 mybr0 bridge local
  10. 968a94b5a0b7 none null local
  11. ## 启动一个容器并连接到已创建mybr0网络
  12. ocker run -it --network mybr0 --rm busybox
  13. Unable to find image 'busybox:latest' locally
  14. latest: Pulling from library/busybox
  15. 5cc84ad355aa: Pull complete
  16. Digest: sha256:5acba83a746c7608ed544dc1533b87c737a0b0fb730301639a0179f9344b1678
  17. Status: Downloaded newer image for busybox:latest
  18. / # ifconfig
  19. eth0 Link encap:Ethernet HWaddr 02:42:C0:A8:64:02
  20. inet addr:192.168.100.2 Bcast:192.168.100.255 Mask:255.255.255.0
  21. UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
  22. RX packets:12 errors:0 dropped:0 overruns:0 frame:0
  23. TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
  24. collisions:0 txqueuelen:0
  25. RX bytes:1032 (1.0 KiB) TX bytes:0 (0.0 B)
  26. lo Link encap:Local Loopback
  27. inet addr:127.0.0.1 Mask:255.0.0.0
  28. UP LOOPBACK RUNNING MTU:65536 Metric:1
  29. RX packets:0 errors:0 dropped:0 overruns:0 frame:0
  30. TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
  31. collisions:0 txqueuelen:1000
  32. RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
  33. / #

host
  1. #查看host网络模型的详细信息
  2. docker network inspect host
  3. ## 输出
  4. [
  5. {
  6. "Name": "host",
  7. "Id": "724b9c2a701cc6840537eeeb0caf30282b0f016c4493a32c72dc4135fa499596",
  8. "Created": "2022-06-11T03:45:01.729475801-04:00",
  9. "Scope": "local",
  10. "Driver": "host",
  11. "EnableIPv6": false,
  12. "IPAM": {
  13. "Driver": "default",
  14. "Options": null,
  15. "Config": []
  16. },
  17. "Internal": false,
  18. "Attachable": false,
  19. "Ingress": false,
  20. "ConfigFrom": {
  21. "Network": ""
  22. },
  23. "ConfigOnly": false,
  24. "Containers": {},
  25. "Options": {},
  26. "Labels": {}
  27. }
  28. ]
  29. #创建容器使用host网络模型,并查看其网络信息
  30. docker run -it --network host --rm busybox
  31. ## 输出
  32. / # ifconfig
  33. docker0 Link encap:Ethernet HWaddr 02:42:93:A6:9C:60
  34. inet addr:172.17.0.1 Bcast:172.17.255.255 Mask:255.255.0.0
  35. inet6 addr: fe80::42:93ff:fea6:9c60/64 Scope:Link
  36. UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
  37. RX packets:5984180 errors:0 dropped:0 overruns:0 frame:0
  38. TX packets:6165023 errors:0 dropped:0 overruns:0 carrier:0
  39. collisions:0 txqueuelen:0
  40. RX bytes:1383940963 (1.2 GiB) TX bytes:1659580303 (1.5 GiB)
  41. docker1 Link encap:Ethernet HWaddr 02:42:F0:D2:59:10
  42. inet addr:192.168.100.1 Bcast:192.168.100.255 Mask:255.255.255.0
  43. inet6 addr: fe80::42:f0ff:fed2:5910/64 Scope:Link
  44. UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
  45. RX packets:0 errors:0 dropped:0 overruns:0 frame:0
  46. TX packets:5 errors:0 dropped:0 overruns:0 carrier:0
  47. collisions:0 txqueuelen:0
  48. RX bytes:0 (0.0 B) TX bytes:446 (446.0 B)
  49. ens33 Link encap:Ethernet HWaddr 00:0C:29:D9:4D:57
  50. inet addr:10.0.0.10 Bcast:10.0.0.255 Mask:255.255.255.0
  51. inet6 addr: fe80::8177:edd2:29e5:e005/64 Scope:Link
  52. UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
  53. RX packets:1700192 errors:0 dropped:0 overruns:0 frame:0
  54. TX packets:202787 errors:0 dropped:0 overruns:0 carrier:0
  55. collisions:0 txqueuelen:1000
  56. RX bytes:2418047588 (2.2 GiB) TX bytes:39141361 (37.3 MiB)
  57. lo Link encap:Local Loopback
  58. inet addr:127.0.0.1 Mask:255.0.0.0
  59. inet6 addr: ::1/128 Scope:Host
  60. UP LOOPBACK RUNNING MTU:65536 Metric:1
  61. RX packets:8 errors:0 dropped:0 overruns:0 frame:0
  62. TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
  63. collisions:0 txqueuelen:1000
  64. RX bytes:656 (656.0 B) TX bytes:656 (656.0 B)
  65. veth6bba319 Link encap:Ethernet HWaddr AA:29:EA:47:82:CA
  66. inet6 addr: fe80::a829:eaff:fe47:82ca/64 Scope:Link
  67. UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
  68. RX packets:0 errors:0 dropped:0 overruns:0 frame:0
  69. TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
  70. collisions:0 txqueuelen:0
  71. RX bytes:0 (0.0 B) TX bytes:656 (656.0 B)
  72. veth83e2c83 Link encap:Ethernet HWaddr 4A:3D:0F:00:20:73
  73. inet6 addr: fe80::483d:fff:fe00:2073/64 Scope:Link
  74. UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
  75. RX packets:0 errors:0 dropped:0 overruns:0 frame:0
  76. TX packets:13 errors:0 dropped:0 overruns:0 carrier:0
  77. collisions:0 txqueuelen:0
  78. RX bytes:0 (0.0 B) TX bytes:1102 (1.0 KiB)
  79. veth9986df3 Link encap:Ethernet HWaddr CE:07:3E:CA:12:43
  80. inet6 addr: fe80::cc07:3eff:feca:1243/64 Scope:Link
  81. UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
  82. RX packets:0 errors:0 dropped:0 overruns:0 frame:0
  83. TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
  84. collisions:0 txqueuelen:0
  85. RX bytes:0 (0.0 B) TX bytes:656 (656.0 B)

none
  1. ##查看none网络模型详细信息
  2. docker network inspect none
  3. ## 输出
  4. [
  5. {
  6. "Name": "none",
  7. "Id": "968a94b5a0b7ec56228e4c406b5f5268ce578c821942cd4a060ea7b54dae2741",
  8. "Created": "2022-06-11T03:45:01.722740307-04:00",
  9. "Scope": "local",
  10. "Driver": "null",
  11. "EnableIPv6": false,
  12. "IPAM": {
  13. "Driver": "default",
  14. "Options": null,
  15. "Config": []
  16. },
  17. "Internal": false,
  18. "Attachable": false,
  19. "Ingress": false,
  20. "ConfigFrom": {
  21. "Network": ""
  22. },
  23. "ConfigOnly": false,
  24. "Containers": {},
  25. "Options": {},
  26. "Labels": {}
  27. }
  28. ## 创建容器
  29. docker run -it --network none --rm busybox:latest
  30. ## 输出
  31. / # ifconfig
  32. lo Link encap:Local Loopback
  33. inet addr:127.0.0.1 Mask:255.0.0.0
  34. UP LOOPBACK RUNNING MTU:65536 Metric:1
  35. RX packets:0 errors:0 dropped:0 overruns:0 frame:0
  36. TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
  37. collisions:0 txqueuelen:1000
  38. RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
  39. / #

联盟网络
  1. docker run -it --name c1 --rm busybox:latest
  2. / # ifconfig
  3. eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:03
  4. inet addr:172.17.0.3 Bcast:172.17.255.255 Mask:255.255.0.0
  5. UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
  6. RX packets:8 errors:0 dropped:0 overruns:0 frame:0
  7. TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
  8. collisions:0 txqueuelen:0
  9. RX bytes:656 (656.0 B) TX bytes:0 (0.0 B)
  10. lo Link encap:Local Loopback
  11. inet addr:127.0.0.1 Mask:255.0.0.0
  12. UP LOOPBACK RUNNING MTU:65536 Metric:1
  13. RX packets:0 errors:0 dropped:0 overruns:0 frame:0
  14. TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
  15. collisions:0 txqueuelen:1000
  16. RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
  17. /
  18. [root@localhost tomcat]# docker run -it --name c2 --network container:c1 --rm busybox:latest
  19. / # ifconfig
  20. eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:03
  21. inet addr:172.17.0.3 Bcast:172.17.255.255 Mask:255.255.0.0
  22. UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
  23. RX packets:8 errors:0 dropped:0 overruns:0 frame:0
  24. TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
  25. collisions:0 txqueuelen:0
  26. RX bytes:656 (656.0 B) TX bytes:0 (0.0 B)
  27. lo Link encap:Local Loopback
  28. inet addr:127.0.0.1 Mask:255.0.0.0
  29. UP LOOPBACK RUNNING MTU:65536 Metric:1
  30. RX packets:0 errors:0 dropped:0 overruns:0 frame:0
  31. TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
  32. collisions:0 txqueuelen:1000
  33. RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
  34. / #
  35. c2容器中创建文件并开启httpd服务
  36. / # echo "hello world" >> /tmp/index.html
  37. / # ls /tmp
  38. index.html
  39. / # httpd -h /tmp
  40. 验证80端口是否打开
  41. / # netstat -npl
  42. Active Internet connections (only servers)
  43. Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
  44. tcp 0 0 :::80 :::* LISTEN 10/httpd
  45. Active UNIX domain sockets (only servers)
  46. Proto RefCnt Flags Type State I-Node PID/Program name Path
  47. c1容器中进行访问验证
  48. docker exec c1 wget -O - -q 127.0.0.1
  49. #查看c1容器/tmp目录,发现没有在c2容器中创建的文件,说明c1与c2仅共享了网络命名空间,没有共享文件系统
  50. docker exec c1 ls /tmp
  51. [root@localhost tomcat]# docker exec c1 ls /tmp
  52. [root@localhost tomcat]#

2.4 跨Docker Host容器间通信实现

跨Docker Host容器间通信必要性

  • 由于Docker容器运行的环境类似于在局域网中运行服务一样,无法直接被外界访问,如果采用在Docker Host利用端口映射方式会导致端口被严重消耗。
  • 能够实现不同的Docker Host方便访问其它Docker Host之上的容器提供的服务

    跨Docker Host容器间通信实现方案

    Docker原生方案

  • overlay

    • 基于VXLAN封装实现Docker原生overlay网络
  • macvlan
    • Docker主机网卡接口逻辑上分为多个子接口,每个子接口标识一个VLAN,容器接口直接连接Docker Host
  • 网卡接口

    • 通过路由策略转发到另一台Docker Host

      第三方方案

      隧道方案
  • Flannel

    • 支持UDP和VLAN封装传输方式
  • Weave
    • 支持UDP和VXLAN
  • OpenvSwitch

    路由方案
  • Calico

    • 支持BGP协议和IPIP隧道
    • 每台宿主机作为虚拟路由,通过BGP协议实现不同主机容器间通信。

      2.5 Flannel

      overlay network介绍

      Overlay网络是指在不改变现有网络基础设施的前提下,通过某种约定通信协议,把二层报文封装在IP报文之上的新的数据格式。这样不但能够充分利用成熟的IP路由协议进程数据分发;而且在Overlay技术中采用扩展的隔离标识位数,能够突破VLAN的4000数量限制支持高达16M的用户,并在必要时可将广播流量转化为组播流量,避免广播数据泛滥。
      因此,Overlay网络实际上是目前最主流的容器跨节点数据传输和路由方案。

      Flannel介绍

      Flannel是 CoreOS 团队针对 Kubernetes 设计的一个覆盖网络(Overlay Network)工具,其目的在于帮助每一个使用 Kuberentes 的 CoreOS 主机拥有一个完整的子网。 Flannel通过给每台宿主机分配一个子网的方式为容器提供虚拟网络,它基于Linux TUN/TAP,使用UDP封装IP包来创建overlay网络,并借助etcd维护网络的分配情况。 Flannel is a simple and easy way to configure a layer 3 network fabric designed for Kubernetes.

      Flannel工作原理

      Flannel是CoreOS团队针对Kubernetes设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址。但在默认的Docker配置中,每个Node的Docker服务会分别负责所在节点容器的IP分配。Node内部的容器之间可以相互访问,但是跨主机(Node)网络相互间是不能通信。Flannel设计目的就是为集群中所有节点重新规划IP地址的使用规则,从而使得不同节点上的容器能够获得”同属一个内网”且”不重复的”IP地址,并让属于不同节点上的容器能够直接通过内网IP通信。 Flannel 使用etcd存储配置数据和子网分配信息。flannel 启动之后,后台进程首先检索配置和正在使用的子网列表,然后选择一个可用的子网,然后尝试去注册它。etcd也存储这个每个主机对应的ip。flannel 使用etcd的watch机制监视/coreos.com/network/subnets下面所有元素的变化信息,并且根据它来维护一个路由表。为了提高性能,flannel优化了Universal TAP/TUN设备,对TUN和UDP之间的ip分片做了代理。 如下原理图:
      image-20220209230459054.png
      1. 1、数据从源容器中发出后,经由所在主机的docker0虚拟网卡转发到flannel0虚拟网卡,这是个P2P的虚拟网卡,flanneld服务监听在网卡的另外一端。
      2. 2Flannel通过Etcd服务维护了一张节点间的路由表,该张表里保存了各个节点主机的子网网段信息。
      3. 3、源主机的flanneld服务将原本的数据内容UDP封装后根据自己的路由表投递给目的节点的flanneld服务,数据到达以后被解包,然后直接进入目的节点的flannel0虚拟网卡,然后被转发到目的主机的docker0虚拟网卡,最后就像本机容器通信一样的由docker0路由到达目标容器。

      2.6 ETCD

      etcd是CoreOS团队于2013年6月发起的开源项目,它的目标是构建一个高可用的分布式键值(key-value)数据库。etcd内部采用raft协议作为一致性算法,etcd基于Go语言实现。
      etcd作为服务发现系统,特点:
  • 简单:安装配置简单,而且提供了HTTP API进行交互,使用也很简单

  • 安全:支持SSL证书验证
  • 快速:根据官方提供的benchmark数据,单实例支持每秒2k+读操作
  • 可靠:采用raft算法,实现分布式系统数据的可用性和一致性

    2.7 ETCD部署

    10.0.0.20 和10.0.0.21 两个环境
    主机防火墙及SELINUX均关闭。

    主机名称配置

    1. hostnamectl set-hostname node1
    2. hostnamectl set-hostname node2

    主机名与IP地址解析(两个环境都需要配置)

    1. vim /etc/hosts
    2. [root@node1 ~]# cat /etc/hosts
    3. 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
    4. ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
    5. 10.0.0.20 node1
    6. 10.0.0.21 node2

    开启内核转发

    1. ## 所有的Docker Host 内核都需要
    2. # vim /etc/sysctl.conf
    3. [root@node1 ~]# cat /etc/sysctl.conf
    4. ......
    5. net.ipv4.ip_forward=1
    6. ##
    7. sysctl -p

    etcd安装

    1. ## 两个环境都需要安装
    2. yum -y install etcd

    etcd配置

    1. #[Member]
    2. #ETCD_CORS=""
    3. ETCD_DATA_DIR="/var/lib/etcd/node1.etcd"
    4. #ETCD_WAL_DIR=""
    5. ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
    6. ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379,http://0.0.0.0:4001"
    7. #ETCD_MAX_SNAPSHOTS="5"
    8. #ETCD_MAX_WALS="5"
    9. ETCD_NAME="node1"
    10. #ETCD_SNAPSHOT_COUNT="100000"
    11. #ETCD_HEARTBEAT_INTERVAL="100"
    12. #ETCD_ELECTION_TIMEOUT="1000"
    13. #ETCD_QUOTA_BACKEND_BYTES="0"
    14. #ETCD_MAX_REQUEST_BYTES="1572864"
    15. #ETCD_GRPC_KEEPALIVE_MIN_TIME="5s"
    16. #ETCD_GRPC_KEEPALIVE_INTERVAL="2h0m0s"
    17. #ETCD_GRPC_KEEPALIVE_TIMEOUT="20s"
    18. #
    19. #[Clustering]
    20. ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.0.0.20:2380"
    21. ETCD_ADVERTISE_CLIENT_URLS="http://10.0.0.20:2379,http://10.0.0.20:4001"
    22. #ETCD_DISCOVERY=""
    23. #ETCD_DISCOVERY_FALLBACK="proxy"
    24. #ETCD_DISCOVERY_PROXY=""
    25. #ETCD_DISCOVERY_SRV=""
    26. ETCD_INITIAL_CLUSTER="node1=http://10.0.0.20:2380,node2=http://10.0.0.21:2380"
    27. #ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
    28. #ETCD_INITIAL_CLUSTER_STATE="new"
    29. #ETCD_STRICT_RECONFIG_CHECK="true"
    30. #ETCD_ENABLE_V2="true"
    31. #
    32. #[Proxy]
    33. #ETCD_PROXY="off"
    34. #ETCD_PROXY_FAILURE_WAIT="5000"
    35. #ETCD_PROXY_REFRESH_INTERVAL="30000"
    36. #ETCD_PROXY_DIAL_TIMEOUT="1000"
    37. #ETCD_PROXY_WRITE_TIMEOUT="5000"
    38. #ETCD_PROXY_READ_TIMEOUT="0"
    39. #
    40. #[Security]
    41. #ETCD_CERT_FILE=""
    42. #ETCD_KEY_FILE=""
    43. #ETCD_CLIENT_CERT_AUTH="false"
    44. #ETCD_TRUSTED_CA_FILE=""
    45. #ETCD_AUTO_TLS="false"
    46. #ETCD_PEER_CERT_FILE=""
    47. #ETCD_PEER_KEY_FILE=""
    48. #ETCD_PEER_CLIENT_CERT_AUTH="false"
    49. #ETCD_PEER_TRUSTED_CA_FILE=""
    50. #ETCD_PEER_AUTO_TLS="false"
    51. #
    52. #[Logging]
    53. #ETCD_DEBUG="false"
    54. #ETCD_LOG_PACKAGE_LEVELS=""
    55. #ETCD_LOG_OUTPUT="default"
    56. #
    57. #[Unsafe]
    58. #ETCD_FORCE_NEW_CLUSTER="false"
    59. #
    60. #[Version]
    61. #ETCD_VERSION="false"
    62. #ETCD_AUTO_COMPACTION_RETENTION="0"
    63. #
    64. #[Profiling]
    65. #ETCD_ENABLE_PPROF="false"
    66. #ETCD_METRICS="basic"
    67. #
    68. #[Auth]
    69. #ETCD_AUTH_TOKEN="simple"
    1. #[Member]
    2. #ETCD_CORS=""
    3. ETCD_DATA_DIR="/var/lib/etcd/node2.etcd"
    4. #ETCD_WAL_DIR=""
    5. ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
    6. ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379,http://0.0.0.0:4001"
    7. #ETCD_MAX_SNAPSHOTS="5"
    8. #ETCD_MAX_WALS="5"
    9. ETCD_NAME="node2"
    10. #ETCD_SNAPSHOT_COUNT="100000"
    11. #ETCD_HEARTBEAT_INTERVAL="100"
    12. #ETCD_ELECTION_TIMEOUT="1000"
    13. #ETCD_QUOTA_BACKEND_BYTES="0"
    14. #ETCD_MAX_REQUEST_BYTES="1572864"
    15. #ETCD_GRPC_KEEPALIVE_MIN_TIME="5s"
    16. #ETCD_GRPC_KEEPALIVE_INTERVAL="2h0m0s"
    17. #ETCD_GRPC_KEEPALIVE_TIMEOUT="20s"
    18. #
    19. #[Clustering]
    20. ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.0.0.21:2380"
    21. ETCD_ADVERTISE_CLIENT_URLS="http://10.0.0.21:2379,http://10.0.0.21:4001"
    22. #ETCD_DISCOVERY=""
    23. #ETCD_DISCOVERY_FALLBACK="proxy"
    24. #ETCD_DISCOVERY_PROXY=""
    25. #ETCD_DISCOVERY_SRV=""
    26. ETCD_INITIAL_CLUSTER="node1=http://10.0.0.20:2380,node2=http://10.0.0.21:2380"
    27. #ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
    28. #ETCD_INITIAL_CLUSTER_STATE="new"
    29. #ETCD_STRICT_RECONFIG_CHECK="true"
    30. #ETCD_ENABLE_V2="true"
    31. #
    32. #[Proxy]
    33. #ETCD_PROXY="off"
    34. #ETCD_PROXY_FAILURE_WAIT="5000"
    35. #ETCD_PROXY_REFRESH_INTERVAL="30000"
    36. #ETCD_PROXY_DIAL_TIMEOUT="1000"
    37. #ETCD_PROXY_WRITE_TIMEOUT="5000"
    38. #ETCD_PROXY_READ_TIMEOUT="0"
    39. #
    40. #[Security]
    41. #ETCD_CERT_FILE=""
    42. #ETCD_KEY_FILE=""
    43. #ETCD_CLIENT_CERT_AUTH="false"
    44. #ETCD_TRUSTED_CA_FILE=""
    45. #ETCD_AUTO_TLS="false"
    46. #ETCD_PEER_CERT_FILE=""
    47. #ETCD_PEER_KEY_FILE=""
    48. #ETCD_PEER_CLIENT_CERT_AUTH="false"
    49. #ETCD_PEER_TRUSTED_CA_FILE=""
    50. #ETCD_PEER_AUTO_TLS="false"
    51. #
    52. #[Logging]
    53. #ETCD_DEBUG="false"
    54. #ETCD_LOG_PACKAGE_LEVELS=""
    55. #ETCD_LOG_OUTPUT="default"
    56. #
    57. #[Unsafe]
    58. #ETCD_FORCE_NEW_CLUSTER="false"
    59. #
    60. #[Version]
    61. #ETCD_VERSION="false"
    62. #ETCD_AUTO_COMPACTION_RETENTION="0"
    63. #
    64. #[Profiling]
    65. #ETCD_ENABLE_PPROF="false"
    66. #ETCD_METRICS="basic"
    67. #
    68. #[Auth]
    69. #ETCD_AUTH_TOKEN="simple"

    启动etcd服务(node1 和node2 都需要配置)

    1. systemctl enable etcd
    2. systemctl start etcd

    检查端口状态

    1. netstat -tnlp | grep -E "4001|2380"
    2. #输出结果:
    3. tcp6 0 0 :::2380 :::* LISTEN 19691/etcd
    4. tcp6 0 0 :::4001 :::* LISTEN 19691/etcd

    检查etcd集群是否健康

    1. etcdctl -C http://10.0.0.20:2379 cluster-health
    2. 输出
    3. member 24c242139c616766 is healthy: got healthy result from http://10.0.0.20:2379
    4. member 7858c29df0af79b6 is healthy: got healthy result from http://10.0.0.21:2379
    5. cluster is healthy
    6. ## 或者使用 etcdctl member list
    7. etcdctl member list
    8. 24c242139c616766: name=node1 peerURLs=http://10.0.0.20:2380 clientURLs=http://10.0.0.20:2379,http://10.0.0.20:4001 isLeader=false
    9. 7858c29df0af79b6: name=node2 peerURLs=http://10.0.0.21:2380 clientURLs=http://10.0.0.21:2379,http://10.0.0.21:4001 isLeader=true

    Flannel部署

    Flannel安装(node1 node2 全部安装)

    1. yum -y install flannel

    修改Flannel配置文件

    ```shell vim /etc/sysconfig/flanneld

    修改后的flannel内容

    Flanneld configuration options

etcd url location. Point this to the server where etcd runs

FLANNEL_ETCD_ENDPOINTS=”http://10.0.0.20:2379,http://10.0.0.21:2379

etcd config key. This is the configuration key that flannel queries

For address range assignment

FLANNEL_ETCD_PREFIX=”/atomic.io/network”

Any additional options that you want to pass

FLANNEL_OPTIONS=””

FLANNEL_OPTIONS=”—logtostderr=false —log_dir=/var/log/ —etcd-endpoints=http://10.0.0.20:2379,http ://10.0.0.21:2379 —iface=ens33”

  1. ```shell
  2. vim /etc/sysconfig/flanneld
  3. ## 修改后的flannel内容
  4. # Flanneld configuration options
  5. # etcd url location. Point this to the server where etcd runs
  6. FLANNEL_ETCD_ENDPOINTS="http://10.0.0.20:2379,http://10.0.0.21:2379"
  7. # etcd config key. This is the configuration key that flannel queries
  8. # For address range assignment
  9. FLANNEL_ETCD_PREFIX="/atomic.io/network"
  10. # Any additional options that you want to pass
  11. #FLANNEL_OPTIONS=""
  12. FLANNEL_OPTIONS="--logtostderr=false --log_dir=/var/log/ --etcd-endpoints=http://10.0.0.20:2379,http
  13. ://10.0.0.21:2379 --iface=ens33"

配置etcd中关于flannel的key

Flannel使用Etcd进行配置,来保证多个Flannel实例之间的配置一致性,所以需要在etcd上进行如下配置(‘/http://atomic.io/network/config‘这个key与上面的/etc/sysconfig/flannel中的配置项FLANNEL_ETCD_PREFIX是相对应的,错误的话启动就会出错
该ip网段可以任意设定,随便设定一个网段都可以。容器的ip就是根据这个网段进行自动分配的,ip分配后,容器一般是可以对外联网的(网桥模式,只要Docker Host能上网即可。)

  1. etcdctl mk /atomic.io/network/config '{"Network":"172.21.0.0/16"}'
  2. {"Network":"172.21.0.0/16"}

启动Flannel服务

  1. systemctl enable flanneld;systemctl start flanneld启动Flannel服务

查看各node中flannel产生的配置信息

  1. [root@node1 flannel]# cat /run/flannel/subnet.env
  2. FLANNEL_NETWORK=172.21.0.0/16
  3. FLANNEL_SUBNET=172.21.43.1/24
  4. FLANNEL_MTU=1472
  5. FLANNEL_IPMASQ=false
  1. [root@node2 ~]# cat /run/flannel/subnet.env
  2. FLANNEL_NETWORK=172.21.0.0/16
  3. FLANNEL_SUBNET=172.21.51.1/24
  4. FLANNEL_MTU=1472
  5. FLANNEL_IPMASQ=false

Docker网络配置

—bip=172.21.51.1/24 —ip-masq=true —mtu=1472 放置于启动程序后

  1. vim /usr/lib/systemd/system/docker.service
  2. [root@node1 flannel]# cat /usr/lib/systemd/system/docker.service
  3. [Unit]
  4. Description=Docker Application Container Engine
  5. Documentation=https://docs.docker.com
  6. After=network-online.target docker.socket firewalld.service containerd.service
  7. Wants=network-online.target
  8. Requires=docker.socket containerd.service
  9. [Service]
  10. Type=notify
  11. # the default is not to use systemd for cgroups because the delegate issues still
  12. # exists and systemd currently does not support the cgroup feature set required
  13. # for containers run by docker
  14. ExecStart=/usr/bin/dockerd --bip=172.21.43.1/24 --ip-masq=true --mtu=1472
  15. ExecStartPost=/sbin/iptables -P FORWARD ACCEPT
  16. ExecReload=/bin/kill -s HUP $MAINPID
  17. TimeoutSec=0
  18. RestartSec=2
  19. Restart=always
  20. # Note that StartLimit* options were moved from "Service" to "Unit" in systemd 229.
  21. # Both the old, and new location are accepted by systemd 229 and up, so using the old location
  22. # to make them work for either version of systemd.
  23. StartLimitBurst=3
  24. # Note that StartLimitInterval was renamed to StartLimitIntervalSec in systemd 230.
  25. # Both the old, and new name are accepted by systemd 230 and up, so using the old name to make
  26. # this option work for either version of systemd.
  27. StartLimitInterval=60s
  28. # Having non-zero Limit*s causes performance problems due to accounting overhead
  29. # in the kernel. We recommend using cgroups to do container-local accounting.
  30. LimitNOFILE=infinity
  31. LimitNPROC=infinity
  32. LimitCORE=infinity
  33. # Comment TasksMax if your systemd version does not support it.
  34. # Only systemd 226 and above support this option.
  35. TasksMax=infinity
  36. # set delegate yes so that systemd does not reset the cgroups of docker containers
  37. Delegate=yes
  38. # kill only the docker process, not all processes in the cgroup
  39. KillMode=process
  40. OOMScoreAdjust=-500
  41. [Install]
  42. WantedBy=multi-user.target
  1. [root@node2 ~]# cat /usr/lib/systemd/system/docker.service
  2. [Unit]
  3. Description=Docker Application Container Engine
  4. Documentation=https://docs.docker.com
  5. After=network-online.target docker.socket firewalld.service containerd.service
  6. Wants=network-online.target
  7. Requires=docker.socket containerd.service
  8. [Service]
  9. Type=notify
  10. # the default is not to use systemd for cgroups because the delegate issues still
  11. # exists and systemd currently does not support the cgroup feature set required
  12. # for containers run by docker
  13. ExecStart=/usr/bin/dockerd --bip=172.21.51.1/24 --ip-masq=true --mtu=1472
  14. ExecStartPost=/sbin/iptables -P FORWARD ACCEPT
  15. ExecReload=/bin/kill -s HUP $MAINPID
  16. TimeoutSec=0
  17. RestartSec=2
  18. Restart=always
  19. # Note that StartLimit* options were moved from "Service" to "Unit" in systemd 229.
  20. # Both the old, and new location are accepted by systemd 229 and up, so using the old location
  21. # to make them work for either version of systemd.
  22. StartLimitBurst=3
  23. # Note that StartLimitInterval was renamed to StartLimitIntervalSec in systemd 230.
  24. # Both the old, and new name are accepted by systemd 230 and up, so using the old name to make
  25. # this option work for either version of systemd.
  26. StartLimitInterval=60s
  27. # Having non-zero Limit*s causes performance problems due to accounting overhead
  28. # in the kernel. We recommend using cgroups to do container-local accounting.
  29. LimitNOFILE=infinity
  30. LimitNPROC=infinity
  31. LimitCORE=infinity
  32. # Comment TasksMax if your systemd version does not support it.
  33. # Only systemd 226 and above support this option.
  34. TasksMax=infinity
  35. # set delegate yes so that systemd does not reset the cgroups of docker containers
  36. Delegate=yes
  37. # kill only the docker process, not all processes in the cgroup
  38. KillMode=process
  39. OOMScoreAdjust=-500
  40. [Install]
  41. WantedBy=multi-user.target
  1. systemctl daemon-reload
  2. systemctl restart docker

跨Docker Host容器间通信验证

  1. docker run -it --rm busybox:latest
  2. / # ifconfig
  3. eth0 Link encap:Ethernet HWaddr 02:42:AC:15:2B:02
  4. inet addr:
  5. / # ping 172.21.43.2
  6. PING 172.21.43.2 (172.21.43.2): 56 data bytes
  7. 64 bytes from 172.21.43.2: seq=0 ttl=60 time=1.177 ms
  8. 64 bytes from 172.21.43.2: seq=1 ttl=60 time=0.578 ms
  9. 64 bytes from 172.21.43.2: seq=2 ttl=60 time=0.893 ms
  10. 64 bytes from 172.21.43.2: seq=3 ttl=60 time=0.801 ms
  11. 64 bytes from 172.21.43.2: seq=4 ttl=60 time=0.535 ms
  12. 64 bytes from 172.21.43.2: seq=5 ttl=60 time=1.127 ms
  13. 64 bytes from 172.21.43.2: seq=6 ttl=60 time=0.501 ms
  14. 64 bytes from 172.21.43.2: seq=7 ttl=60 time=0.531 ms
  15. Bcast:172.21.43.255 Mask:255.255.255.0
  16. UP BROADCAST RUNNING MULTICAST MTU:1472 Metric:1
  17. RX packets:13 errors:0 dropped:0 overruns:0 frame:0
  18. TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
  19. collisions:0 txqueuelen:0
  20. RX bytes:1102 (1.0 KiB) TX bytes:0 (0.0 B)
  21. lo Link encap:Local Loopback
  22. inet addr:127.0.0.1 Mask:255.0.0.0
  23. UP LOOPBACK RUNNING MTU:65536 Metric:1
  24. RX packets:0 errors:0 dropped:0 overruns:0 frame:0
  25. TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
  26. collisions:0 txqueuelen:1000
  27. RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
  28. / #
  1. docker run -it --rm busybox:latest
  2. / # ifconfig
  3. eth0 Link encap:Ethernet HWaddr 02:42:AC:15:33:02
  4. inet addr:172.21.51.2 Bcast:172.21.51.255 Mask:255.255.255.0
  5. UP BROADCAST RUNNING MULTICAST MTU:1472 Metric:1
  6. RX packets:12 errors:0 dropped:0 overruns:0 frame:0
  7. TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
  8. collisions:0 txqueuelen:0
  9. RX bytes:1032 (1.0 KiB) TX bytes:0 (0.0 B)
  10. lo Link encap:Local Loopback
  11. inet addr:127.0.0.1 Mask:255.0.0.0
  12. UP LOOPBACK RUNNING MTU:65536 Metric:1
  13. RX packets:0 errors:0 dropped:0 overruns:0 frame:0
  14. TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
  15. collisions:0 txqueuelen:1000
  16. RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
  17. ## ping node1 中的busbox ip
  18. / # ping 172.21.43.2
  19. PING 172.21.43.2 (172.21.43.2): 56 data bytes
  20. 64 bytes from 172.21.43.2: seq=0 ttl=60 time=1.177 ms
  21. 64 bytes from 172.21.43.2: seq=1 ttl=60 time=0.578 ms
  22. 64 bytes from 172.21.43.2: seq=2 ttl=60 time=0.893 ms
  23. 64 bytes from 172.21.43.2: seq=3 ttl=60 time=0.801 ms
  24. 64 bytes from 172.21.43.2: seq=4 ttl=60 time=0.535 ms
  25. 64 bytes from 172.21.43.2: seq=5 ttl=60 time=1.127 ms
  26. 64 bytes from 172.21.43.2: seq=6 ttl=60 time=0.501 ms
  27. 64 bytes from 172.21.43.2: seq=7 ttl=60 time=0.531 ms
  28. ## 可以ping通 说明 跨docker host 容器间通信验证成功

容器数据持久化存储机制

Docker容器数据持久化存储介绍

  • 物理机或虚拟机数据持久化存储
    • 由于物理机或虚拟机本身就拥有大容量的磁盘,所以可以直接把数据存储在物理机或虚拟机本地文件系统中,亦或者也可以通过使用额外的存储系统(NFS、GlusterFS、Ceph等)来完成数据持久化存储。
  • Docker容器数据持久化存储

    • 由于Docker容器是由容器镜像生成的,所以一般容器镜像中包含什么文件或目录,在容器启动后,我们依旧可以看到相同的文件或目录。
    • 由于Docker容器属于“用后即焚”型计算资源,因此Docker容器不适合做数据持久化存储

      Docker容器数据持久化存储方式

      Docker提供三种方式将数据从宿主机挂载到容器中:
  • docker run -v

    • 运行容器时,直接挂载本地目录至容器中
      1. 运行web3容器,挂载未创建的本地目录,启动容器时将自动创建本地目录
      2. docker run -d --name web3 -v /opt/web3root/:/usr/share/nginx/html/ nginx:latest
      3. 往自动创建的目录中添加一个index.html文件
      4. # echo "kubemsb web3" > /opt/web3root/index.html
      5. 在容器中执行查看文件命令
      6. # docker exec web3 cat /usr/share/nginx/html/index.html
      7. kubemsb web3
  • volumes

    • Docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)
    • 是Docker默认存储数据方式
      1. #创建一个名称为nginx-vol的数据卷
      2. docker volume create nginx-vol
      3. #使用数据卷
      4. docker run -d --name web4 -v nginx-vol:/usr/share/nginx/html/ nginx:latest
      5. 或者
      6. docker run -d --name web4 --mount src=nginx-vol,dst=/usr/share/nginx/html nginx:latest
  • bind mounts

    • 将宿主机上的任意位置文件或目录挂载到容器中
      1. 创建用于容器挂载的目录web5root
      2. mkdir /opt/web5root
      3. #运行web5容器并使用bind mount方法实现本地任意目录挂载
      4. docker run -d --name web5 --mount type=bind,src=/opt/web5root,dst=/usr/share/nginx/html nginx:latest
      5. 添加内容至/opt/web5root/index.html
      6. # echo "web5" > /opt/web5root/index.html
      7. 使用curl命令访问容器
      8. # curl http://172.17.0.3
      9. web5