系统学devops系列: docker入门学习操作篇

内容 隐藏

1.docker 入门安装

1.1 ubuntu系统安装docker-ce

ubuntu下安装docker-ce

1.2 centos系统安装docker-ce

1.2.1.移除旧版本

yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

1.2.2.安装依赖软件包

yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2

1.2.3.添加软件仓库

我们这里使用稳定版 Docker,执行下面命令添加 yum 仓库地址:
yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

1.2.4.安装docker

yum install docker-ce

1.2.5 指定安装版本安装

yum list docker-ce --showduplicates | sort -r
yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io

1.3 通过阿里云自动脚本安装

curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

1.4 安装后的一些操作

1.4.1 普通用户操作docker

usermod -aG docker your-user

1.4.2 启动 Docker

systemctl enable docker
systemctl start docker

1.4.3 安装版本系统查看

[root@node01 ~]# docker version
Client:
 Version:           18.09.1
 API version:       1.39
 Go version:        go1.10.6
 Git commit:        4c52b90
 Built:             Wed Jan  9 19:35:01 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.1
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.6
  Git commit:       4c52b90
  Built:            Wed Jan  9 19:06:30 2019
  OS/Arch:          linux/amd64
  Experimental:     false

1.4.4 配置Docker加速器

vim /etc/docker/daemon.json
{
    "registry-mirrors": ["https://registry.docker-cn.com","http://hub-mirror.c.163.com"]
}
重启docker
systemctl daemon-reload
systemctl restart docker

验证加速配置是否加载
[root@node01 ~]# docker info |grep -A 3 "Registry Mirrors"

Registry Mirrors:
 https://registry.docker-cn.com/
 http://hub-mirror.c.163.com/

1.4.5 一些国内外的镜像地址

国内镜像地址

docker官网中国区镜像
--registry-mirror=https://registry.docker-cn.com
网易163 docker镜像 未使用,请自行判断
--registry-mirror=http://hub-mirror.c.163.com
USTC镜像加速
--registry-mirror=https://docker.mirrors.ustc.edu.cn
daocloud镜像 需注册
--registry-mirror=http://{your_id}.m.daocloud.io
alicloud 注册后有自己的加速地址
--registry-mirror=https://{your_id}.mirror.aliyuncs.com

1.5 卸载docker-ce

yum remove docker-ce
rm -rf /var/lib/docker

2.镜像管理

2.1 镜像的理论

Docker 的镜像是分层存储,每一个镜像都是由很多层,很多个文件组成。好处是共享资源。 多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享

用户不需要关心容器最终会在哪里运行,因为哪里都可以运行。
开发人员可以在笔记本上构建镜像并上传到 Registry,然后 QA 人员将镜像下载到物理或虚拟机做测试,最终容器会部署到生产环境。
使用 Docker 以及容器技术,我们可以快速构建一个应用服务器、一个消息中间件、一个数据库、一个持续集成环境。因为 Docker Hub 上有我们能想到的几乎所有的镜像。
镜像和容器的关系:
一个镜像可以创建多个容器。
镜像是增量式存储。
创建的容器里面修改不会影响到镜像。
docker commit 可以将容器提交成新的镜像。即Docker 支持通过扩展现有镜像,创建新的镜像。
容器只能使用Host的kernel,并且不能修改。

2.2 容器Copy-on-Write特性

新数据会直接存放在最上面的容器层。
修改现有数据会先从镜像层将数据复制到容器层,修改后的数据直接保存在容器层中,镜像层保持不变。
如果多个层中有命名相同的文件,用户只能看到最上面那层中的文件。

2.3 可写的容器层

当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。
典型的Linux在启动后,首先将 rootfs 置为 readonly, 进行一系列检查, 然后将其切换为 “readwrite” 供用户使用。在docker中,起初也是将 rootfs 以readonly方式加载并检查,然而接下来利用 union mount 的将一个 readwrite 文件系统挂载在 readonly 的rootfs之上,并且允许再次将下层的 file system设定为readonly 并且向上叠加, 这样一组readonly和一个writeable的结构构成一个container的运行目录, 每一个被称作一个Layer。
所有对容器的改动,无论添加、删除、还是修改文件都只会发生在容器层中。只有容器层是可写的,容器层下面的所有镜像层都是只读的。
在容器层中,用户看到的是一个叠加之后的文件系统。
容器层记录对镜像的修改,所有镜像层都是只读的,不会被容器修改,所以镜像可以被多个容器共享。

2.4 管理镜像常用命令

ls       列出镜像
build    构建镜像来自dockerfinle
history  查看镜像历史
inspect  显示一个或多个镜像详细信息
pull    从镜像仓库拉取镜像
push    推送一个镜像到镜像仓库
rm      移除一个或者多个镜像
prune   移除未使用的镜像
tag     创建一个引用源镜像标记目标镜像 
export  导出容器文件系统到tar归档文件 
import  导入容器文件系统tar归档文件创建镜像
save 保存一个或者多个镜像到一个tar归档文件
load  加载镜像来自tar归档或者标准输入

2.5 docker创建镜像方式

docker创建镜像有docker commit 和docker build基于dockerfile创建镜像。
不推荐使用docker commit创建镜像,因为commit创建的镜像可复用性低,容易出错,安全性无法保证。

推荐使用 Dockerfile 方法来代替 docker commit,因为通过前者构建镜像更具备可重复性、透明性以及幂等性。

2.6 通过docker file创建一个镜像

 cat dockerfile 
FROM ubuntu
RUN sed -i 's/archive.ubuntu.com/cn.archive.ubuntu.com/g' /etc/apt/sources.list
RUN sed -i 's/security.ubuntu/cn.archive.ubuntu/g' /etc/apt/sources.list
RUN apt-get -y update && apt-get -y install apache2
EXPOSE 80

执行docker build创建
[root@node01 ~/tmp]# docker build -t ubuntu_with_apache_dockerfile .    
Sending build context to Docker daemon  2.048kB
Step 1/5 : FROM ubuntu
latest: Pulling from library/ubuntu
2746a4a261c9: Pulling fs layer 
4c1d20cdee96: Pulling fs layer 
0d3160e1d0de: Downloading 
c8e37668deea: Waiting 
latest: Pulling from library/ubuntu
2746a4a261c9: Pull complete 
4c1d20cdee96: Pull complete 
0d3160e1d0de: Pull complete 
c8e37668deea: Pull complete 
Digest: sha256:250cc6f3f3ffc5cdaa9d8f4946ac79821aafb4d3afc93928f0de9336eba21aa4
Status: Downloaded newer image for ubuntu:latest
 ---> 549b9b86cb8d
Step 2/5 : RUN sed -i 's/archive.ubuntu.com/cn.archive.ubuntu.com/g' /etc/apt/sources.list
 ---> Running in a1e5ceb597cf
Removing intermediate container a1e5ceb597cf
 ---> 88d2aef76ef6
Step 3/5 : RUN sed -i 's/security.ubuntu/cn.archive.ubuntu/g' /etc/apt/sources.list
 ---> Running in 2414f702ca47
Removing intermediate container 2414f702ca47
 ---> 597d2e8dd6de
Step 4/5 : RUN apt-get -y update && apt-get -y install apache2
 ---> Running in 67c06f0c132b
Get:1 http://cn.archive.ubuntu.com/ubuntu bionic InRelease [242 kB]
Get:2 http://cn.archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]
Get:3 http://cn.archive.ubuntu.com/ubuntu bionic-backports InRelease [74.6 kB]
Get:4 http://cn.archive.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]
Get:5 http://cn.archive.ubuntu.com/ubuntu bionic/restricted amd64 Packages [13.5 kB]
Get:6 http://cn.archive.ubuntu.com/ubuntu bionic/main amd64 Packages [1344 kB]
Get:6 http://cn.archive.ubuntu.com/ubuntu bionic/main amd64 Packages [1344 kB]
Get:6 http://cn.archive.ubuntu.com/ubuntu bionic/main amd64 Packages [1344 kB]
Get:6 http://cn.archive.ubuntu.com/ubuntu bionic/main amd64 Packages [1344 kB]

3.容器选项

3.1 启动容器常用命令

命令 解释
-i 交互式
-t 分配伪终端
-d 运行容器到后台
-e 设置环境变量
-p 发布容器端口到主机
-P 发布容器所有expose端口到宿主机随机端口
-name 指定容器名称
-h 设置容器主机名
-ip 指定容器ip,只能用于自定义网络
-network 链接容器到一个网络
-mount 将文件系统附加到容器
-v 绑定挂载一个卷
-restart 容器退出时重启策略,默认no,可选值:always|on-failure
例子:
docker run -itd  -e JAVA_HOME=/usr/local/java --name test -h java-test java
查看
[root@node01 ~]# docker exec -it f4b63d68bbb7  bash 
root@java-test:/# cat /etc/hostname 
java-test
root@java-test:/# echo $JAVA_HOME
/usr/local/java

3.2 容器资源限制命令

命令 解释
-m,-memory 容器可以使用的最大内存
-memory-swap 允许交换到磁盘的内存量
-memory-swappiness= 容器允许使用swap分区交换的百分比(默认-1)
-oom-kill-disable 禁止使用oom killer
--cpus 可以使用cpu数量
--cpuset-cpus 限制容器使用特定的cpu核心
-cpu-shares cpu共享(相对权重)
例子:
内存限额
允许容器最多使用500M内存和100M的swap,并禁用oom killer:

docker run -d --name nginx --memory="500m" --memory-swap="100m" --oom-kill-disable nginx
查看内存是否限制 docker stats 

cpu限额
允许容器最多使用一个半的cpu:
docker run -d --name nginx --cpus="1.5" nginx
允许容器最多使用50%的cpu:
docker run -d --name nginx --cpus=".5" nginx

3.3 管理容器常用命令

选项 描述
ls 列出容器
inspect 查看一个或多个容器信息
exec 在运行的容器中执行命令
commit 创建一个新的容器来自一个容器
cp 拷贝文件/文件夹到容器
logs 查看容器日志
port 列出容器端口映射
top 显示一个容器运行的进程
stats 显示容器资源使用情况
stop/start 停止/启动容器
rm 删除容器
 docker 可以结合shell去操作
删除所有容器:
docker rm  -f (docker ps -a |awk -F "{print1}")
docker ps -q #查看容器pid

4.管理应用程序数据

4.1 数据挂载的三种方式

Docker提供三种方式将数据从宿主机挂载到容器中:
volumes:Docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)。保存数据的最佳方式。
bind mounts:将宿主机上的任意位置的文件或者目录挂载到容器中。
tmpfs:挂载存储在主机系统的内存中,而不会写入主机的文件系统。如果不希望将数据持久存储在任何位置,可以使用
tmpfs,同时避免写入容器可写层提高性能.

4.2 volume方式挂载

[root@node01 ~]# docker volume
Usage:  docker volume COMMAND
Manage volumes
Commands:
  create      Create a volume
  inspect     Display detailed information on one or more volumes
  ls          List volumes
  prune       Remove all unused local volumes
  rm          Remove one or more volumes

管理卷:
docker volume create nginx-vol
docker volume ls
docker volume inspect nginx-vol

如下可以查看卷的详细信息,如所在的位置
[root@node01 ~]# docker volume inspect nginx-vol
[
    {
        "CreatedAt": "2020-02-22T22:48:54+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/nginx-vol/_data",
        "Name": "nginx-vol",
        "Options": {},
        "Scope": "local"
    }
]

用卷创建一个容器(两种方式):
docker run -d --name=nginx-test --mount src=nginx-vol,dst=/usr/share/nginx/html nginx

验证:
[root@node01 ~]# ls /var/lib/docker/volumes/nginx-vol/_data
50x.html  index.html

docker run -d --name=nginx-test -v nginx-vol:/usr/share/nginx/html nginx
ps:容器删除后卷里的数据不会丢。
清理:
docker stop nginx-test
docker rm nginx-test 
docker volume rm nginx-vol
注意:
1. 如果没有指定卷,自动创建。
2. 建议使用--mount,更通用。

4.3 bind mounts方式挂载数据

用卷创建一个容器:
docker run -d -it --name=nginx-test --mount type=bind,src=/app/wwwroot,dst=/usr/share/nginx/html nginx
docker run -d -it --name=nginx-test -v /app/wwwroot:/usr/share/nginx/html nginx
ps: 通过-v的方式 没有这个目录会自动创建。
验证绑定:
docker inspect nginx-test
清理:
docker stop nginx-test 
docker rm nginx-test 
注意:
1. 如果源文件/目录没有存在,不会自动创建,会抛出一个错误。
如下:
docker run -d -it --name=nginx  --mount type=bind,src=/app/wwroot,dst=/usr/share/nginx/html nginx 
docker: Error response from daemon: invalid mount config for type "bind": bind source path does not exist: /app/wwroot.

2. 如果挂载目标在容器中非空目录,则该目录现有内容将被隐藏

4.4 volume和mounts方式区别

Volume特点: 多个运行容器之间共享数据。
 当容器停止或被移除时,该卷依然存在。
 多个容器可以同时挂载相同的卷。
 当明确删除卷时,卷才会被删除。
 将容器的数据存储在远程主机或其他存储上
 将数据从一台Docker主机迁移到另一台时,先停止容器,然后备份卷的目录(/var/lib/docker/volumes/)
Bind Mounts特点:  从主机共享配置文件到容器。默认情况下,挂载主机/etc/resolv.conf到每个容器,提供DNS解析。
 在Docker主机上的开发环境和容器之间共享源代码。例如,可以将Maven target目录挂载到容器中,每次在Docker主机
上构建Maven项目时,容器都可以访问构建的项目包。
当Docker主机的文件或目录结构保证与容器所需的绑定挂载一致时

5.容器网络

Docker 通过网络驱动来支持容器的网络通信,默认情况下,Docker 提供两种网络驱动供我们使用,一个是 bridge,一个是 overlay。 Docker 安装时会自动在 host 上创建三个网络,我们可用docker network ls命令查看:
[root@node01 /nginx-test]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
a011bbd324b6        bridge              bridge              local
01d886c1f2a5        host                host                local
923ea0e665a3        none                null                local

容器网络访问原理如下图
系统学devops系列: docker入门学习操作篇

5.1 容器的网络模式

None:不为容器配置任何网络功能,--net=none 
host:与主机共享Network Namespace,--net=host
bridge:是 docker 的默认网络模式,不写–net参数,就是bridge模式。使用docker run -p时,docker 实际是在iptables做了DNAT规则,实现端口转发功能。
container:–-net=container:Name/ID
与指定的容器使用同一个network namespace,具有同样的网络配置信息,两个容器除了网络,其他都还是隔离的。
自定义网络
与默认的bridge原理一样,但自定义网络具备内部DNS发现,可以通过容器名或者主机名容器之间网络通信。

5.2 none网络演示

[root@node01 /nginx-test]# docker run -it --network=none busybox
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
bdbbaa22dec6: Pull complete 
Digest: sha256:6915be4043561d64e0ab0f8f098dc2ac48e077fe23f488ac24b665166898115a
Status: Downloaded newer image for busybox:latest
/ # ifconfig
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
ps:挂在这个网络下的容器除了lo,没有其他任何网卡。
场景:比如某个容器的唯一用途是生成随机密码,就可以放到none网络中避免密码被窃取。

5.3 host网络演示

[root@node01 /nginx-test]# docker run -d -it   --network=host busybox
e321ec38d88588a763bf309570cfb400d743e8384877b2d5fb96610c610ead4b
[root@node01 /nginx-test]# docker ps 
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
e321ec38d885        busybox             "sh"                13 seconds ago      Up 8 seconds                            kind_johnson
[root@node01 /nginx-test]# docker exec -it e321ec38d885 sh
/ # ifconfig
docker0   Link encap:Ethernet  HWaddr 02:42:A2:05:9A:73  
          inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0
          inet6 addr: fe80::42:a2ff:fe05:9a73/64 Scope:Link
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:108 errors:0 dropped:0 overruns:0 frame:0
          TX packets:146 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:11371 (11.1 KiB)  TX bytes:17194 (16.7 KiB)

ens33     Link encap:Ethernet  HWaddr 00:0C:29:F9:21:45  
          inet addr:192.168.32.129  Bcast:192.168.32.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fef9:2145/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:20012 errors:0 dropped:0 overruns:0 frame:0
          TX packets:12378 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:9601831 (9.1 MiB)  TX bytes:1248226 (1.1 MiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

可以看到网络是和物理主机共享的。直接使用Docker host的网络最大的好处就是性能,如果容器对网络传输效率有较高要求,则可以选择host网络。当然不便之处就是牺牲一些灵活性,比如要考虑端口冲突问题,Docker host上已经使用的端口就不能再用了。

5.4 bridge网络演示

[root@node01 /nginx-test]# docker run -d -it   --network=bridge busybox
167a93bce224d7baf64d699e8dc3312d29e906796d5f0095d7a03e549115b46e
[root@node01 /nginx-test]# docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
167a93bce224        busybox             "sh"                17 seconds ago      Up 7 seconds                            dazzling_shamir
[root@node01 /nginx-test]# docker exec -it 167a93bce224 sh
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:648 (648.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
默认会分配一个172.17.0.2网段的地址
[root@node01 /nginx-test]# docker network inspect bridge  #bridge网络的配置信息
[
    {
        "Name": "bridge",
        "Id": "a011bbd324b6c23e8fbe2cfc3ac34018b9a4cd602461e25f723ba6b7d8c7750e",
        "Created": "2020-02-23T05:51:22.605647797+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "167a93bce224d7baf64d699e8dc3312d29e906796d5f0095d7a03e549115b46e": {
                "Name": "dazzling_shamir",
                "EndpointID": "9c76dd1906c352b4b93fe1b661e92c6c81a53c4c53b616ed7c49b6b25d5e6b74",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]
ps:bridge网络配置的subnet就是172.17.0.0/16,并且网关是172.17.0.1,网关就是docker0

5.5 自定义网络演示一

与默认的bridge原理一样,但自定义网络具备内部DNS发现,可以通过容器名或者主机名容器之间网络通信.
[root@node01 /nginx-test]# docker network create -d bridge my_network
4e00d67cc88d7f985580fe989b36dcb77a750f37646069e97fd778ee1546ddba
[root@node01 /nginx-test]# docker network ls 
NETWORK ID          NAME                DRIVER              SCOPE
a011bbd324b6        bridge              bridge              local
01d886c1f2a5        host                host                local
4e00d67cc88d        my_network          bridge              local
923ea0e665a3        none                null                local

执行docker network inspect查看一下my_network的配置信息:
[root@node01 /nginx-test]# docker network inspect  my_network
[
    {
        "Name": "my_network",
        "Id": "4e00d67cc88d7f985580fe989b36dcb77a750f37646069e97fd778ee1546ddba",
        "Created": "2020-02-23T22:56:23.364717939+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]
这里172.18.0.0/16是Docker自动分配的IP网段。

[root@node01 /nginx-test]# docker run -itd --network=my_network --name=test02 busybox
21f9bd7cc3415c75d09626a6ff4b20893c10bb6e541fb0d062c7378fcb2cd6ea
[root@node01 /nginx-test]# docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
21f9bd7cc341        busybox             "sh"                11 seconds ago      Up 4 seconds                            test02
[root@node01 /nginx-test]# docker exec -it 21f9bd7cc341  sh
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:12:00:04  
          inet addr:172.18.0.4  Bcast:172.18.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:648 (648.0 B)  TX bytes:0 (0.0 B)

由上可查看,分配的网络是172.18.0.1段的,并且同一网桥的容器是可以通信的。

5.6 自定义网络演示二

如果要自定义网络IP段,只需在创建网段时指定--subnet和--gateway参数:
[root@node01 /nginx-test]# docker network create -d bridge --subnet 192.168.10.0/24 --gateway 192.168.10.1 my_birdge2
4b1136edff7a6a008332295532bdd62be43cebedc647c3647cbdf4a6cdf129a1

[root@node01 /nginx-test]# docker network inspect my_birdge2
[
    {
        "Name": "my_birdge2",
        "Id": "4b1136edff7a6a008332295532bdd62be43cebedc647c3647cbdf4a6cdf129a1",
        "Created": "2020-02-23T23:24:40.806534699+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.10.0/24",
                    "Gateway": "192.168.10.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

通过这个自定义网段创建两个实例,查看地址并查看连通性。
[root@node01 /nginx-test]# docker run -idt  --rm  --network my_birdge2 --name test01 busybox
[root@node01 /nginx-test]# docker run -idt  --rm  --network my_birdge2 --name test02 busybox
[root@node01 /nginx-test]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
bbfe93723e90        busybox             "sh"                24 seconds ago       Up 20 seconds                           test02
dad4139952a5        busybox             "sh"                About a minute ago   Up About a minute                       test01

[root@node01 /nginx-test]# docker exec bbfe93723e90  ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:C0:A8:0A:03  
          inet addr:192.168.10.3  Bcast:192.168.10.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:648 (648.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

[root@node01 /nginx-test]# docker exec -it  dad4139952a5 sh
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:C0:A8:0A:02  
          inet addr:192.168.10.2  Bcast:192.168.10.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:12 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:872 (872.0 B)  TX bytes:182 (182.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ # ping 192.168.10.3
PING 192.168.10.3 (192.168.10.3): 56 data bytes
64 bytes from 192.168.10.3: seq=0 ttl=64 time=0.167 ms

通过如上创建,可知,可以自定义网段,并且同一网桥的容器是互通的。

给容器指定分配静态IP
/ # [root@node01 /nginx-test]# docker run -it --network=my_birdge2 --ip 192.168.10.10 --name busybox3 busybox sh
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:C0:A8:0A:0A  
          inet addr:192.168.10.10  Bcast:192.168.10.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:6 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:508 (508.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ # ping 192.168.10.2
PING 192.168.10.2 (192.168.10.2): 56 data bytes
64 bytes from 192.168.10.2: seq=0 ttl=64 time=0.275 ms
^C
--- 192.168.10.2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.275/0.275/0.275 ms
/ # ping 192.168.10.3
PING 192.168.10.3 (192.168.10.3): 56 data bytes
64 bytes from 192.168.10.3: seq=0 ttl=64 time=0.143 ms

5.7 container网络模式演示

[root@node01 /nginx-test]# docker run -itd --name container1 busybox 
ac2f6ea0f1af156b56b7ae30f6f2b3b5b948b53f9b976ade1dbb398beb091250
[root@node01 /nginx-test]# docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
ac2f6ea0f1af        busybox             "sh"                14 seconds ago      Up 9 seconds                            container1
[root@node01 /nginx-test]# docker exec ac2f6ea0f1af  ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:648 (648.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

[root@node01 /nginx-test]# docker run -it --net container:ac2f6ea0f1af  busybox sh
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:648 (648.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

如上,通过 --net container:ac2f6ea0f1af创建的新容器和ac2f6ea0f1af共享同一个network namespace。

5.8 不同网桥下的容器互通

ip r 查看 host 上的路由表:
[root@node01 /nginx-test]# ip r
default via 192.168.32.2 dev ens33  proto static  metric 100 
172.17.0.0/16 dev docker0  proto kernel  scope link  src 172.17.0.1 
172.18.0.0/16 dev br-4e00d67cc88d  proto kernel  scope link  src 172.18.0.1 
172.19.0.0/16 dev br-3919af935238  proto kernel  scope link  src 172.19.0.1 
172.20.0.0/16 dev br-1b02b4c4c631  proto kernel  scope link  src 172.20.0.1 
192.168.10.0/24 dev br-4b1136edff7a  proto kernel  scope link  src 192.168.10.1 
192.168.32.0/24 dev ens33  proto kernel  scope link  src 192.168.32.129 
192.168.32.0/24 dev ens33  proto kernel  scope link  src 192.168.32.129  metric 100 

开启路由转发
[root@node01 /nginx-test]# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf 
[root@node01 /nginx-test]# sysctl -p
net.ipv4.ip_forward = 1

默认iptables DROP掉了网桥docker0与不同网络的通信之间双向的流量。用于隔离不同的网络。要想让不同网桥下两个容器互联,需要添加网卡,命令docker network connect。
操作如下
[root@node01 /nginx-test]# docker run -itd --name test1 --net test busybox 
39373adfcaf04c4a02c1ba10fa0f29bbe3bf56d0b763f80b361671e07e7f7878
[root@node01 /nginx-test]# docker run -itd --name test2 --net my_birdge2  busybox 
0eca3cdaf834e540a6cff336511ab2a985036ece444bb5eab17a18d6d1d93176
[root@node01 /nginx-test]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
0eca3cdaf834        busybox             "sh"                6 seconds ago       Up 2 seconds                            test2
39373adfcaf0        busybox             "sh"                24 seconds ago      Up 19 seconds                           test1
[root@node01 /nginx-test]# docker exec 0eca3cdaf834 ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:C0:A8:0A:02  
          inet addr:192.168.10.2  Bcast:192.168.10.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:648 (648.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

^[[A[root@node01 /nginx-test]# docker exec 39373adfcaf0  ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:13:00:02  
          inet addr:172.19.0.2  Bcast:172.19.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:648 (648.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

[root@node01 /nginx-test]# docker exec -it 39373adfcaf0 sh
/ # ping 192.168.10.2 
PING 192.168.10.2 (192.168.10.2): 56 data bytes
^C
--- 192.168.10.2 ping statistics ---
5 packets transmitted, 0 packets received, 100% packet loss
/ # 

要想test1和test2 相互通信。需如下操作:
 [root@node01 /nginx-test]# docker network connect  my_birdge2 39373adfcaf0

[root@node01 /nginx-test]# docker exec -it 39373adfcaf0 sh
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:13:00:02  
          inet addr:172.19.0.2  Bcast:172.19.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:9 errors:0 dropped:0 overruns:0 frame:0
          TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:690 (690.0 B)  TX bytes:532 (532.0 B)

eth1      Link encap:Ethernet  HWaddr 02:42:C0:A8:0A:03  
          inet addr:192.168.10.3  Bcast:192.168.10.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:648 (648.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ # ping 192.168.10.2 
PING 192.168.10.2 (192.168.10.2): 56 data bytes
64 bytes from 192.168.10.2: seq=0 ttl=64 time=0.276 ms
^C

 # [root@node01 /nginx-test]# brctl show
bridge name bridge id       STP enabled interfaces
br-1b02b4c4c631     8000.0242d6abe913   no      
br-3919af935238     8000.02427e02320c   no      veth0c5cade
br-4b1136edff7a     8000.02420eae2e5f   no      veth5a3768f
                            vethd33b8f3
br-4e00d67cc88d     8000.024267f0dee0   no      
docker0     8000.0242a2059a73   no      

6.dockerfile

6.1 dockerfile命令

指令 描述
FROM 构建新镜像基于哪个基础镜像
MAINTAINER 设置镜像的作者,可以是任意字符串
RUN 构建镜像时运行的shell
COPY 复制文件或者目录到镜像中
ENV 设置环境变量
USER 为RUN、CMD和ENTRYPOINT执行命令指定运行用户
LABEL 功能是为镜像指定标签
WORKDIR 指定工作目录
EXPOSE 暴露端口
ADD 高级复制文件
HEALTHCHECK 健康检查
VOLUME 指定容器挂载点到宿主机自动生成的目录或其他容器
ENTRYPOINT 设置容器启动时运行的命令

6.2 使用dockerfile构建nginx服务

系统学devops系列: docker入门学习操作篇

6.3 使用dockerfile构建lnmp实例

系统学devops系列: docker入门学习操作篇系统学devops系列: docker入门学习操作篇
部署一个wordpress查看下lnmp搭建
[root@node01 /var/lib/docker/volumes/wwwroot/_data]# wget https://cn.wordpress.org/wordpress-4.9.4-zh_CN.tar.gz
[root@node01 /var/lib/docker/volumes/wwwroot/_data]# tar -xf wordpress-4.9.4-zh_CN.tar.gz
[root@node01 /var/lib/docker/volumes/wwwroot/_data]# mv wordpress/* .
访问http://192.168.32.129:88
系统学devops系列: docker入门学习操作篇
如上图就可以配置我们的博客系统了。

系统学devops系列: docker入门学习操作篇
填写mysql相关信息 ,如构建mysql数据库时的数据库用户名及密码。
如下图,通过dockerfile搭建lnmp就已经成功了,你可以通过dockerfile快速搭建自己的博客系统。
系统学devops系列: docker入门学习操作篇

6.4 使用dockerfile构建tomcat实例

[root@node01 ~/dockerfile/tomcat]# cat docker-tomcat 
FROM centos:7
MAINTAINER devopstack.cn

ENV VERSION=8.5.51

RUN rpm --rebuilddb ; yum install java-1.8.0-openjdk wget curl unzip iproute net-tools -y && \
    yum clean all && \
    rm -rf /var/cache/yum/*

RUN wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v{VERSION}/bin/apache-tomcat-{VERSION}.tar.gz && \
    tar zxf apache-tomcat-{VERSION}.tar.gz && \
    mv apache-tomcat-{VERSION} /usr/local/tomcat && \
    rm -rf apache-tomcat-{VERSION}.tar.gz /usr/local/tomcat/webapps/* && \
    mkdir /usr/local/tomcat/webapps/test && \
    echo "ok">/usr/local/tomcat/webapps/test/status.html && \
    sed -i '1a JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom"' /usr/local/tomcat/bin/catalina.sh && \
    ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

ENV PATHPATH:/usr/local/tomcat/bin

WORKDIR /usr/local/tomcat

EXPOSE 8080
CMD ["catalina.sh", "run"]

构建tomcat镜像
[root@node01 ~/dockerfile/tomcat]# docker build -t tomcat:v1 -f docker-tomcat  .
查看构建结果
[root@node01 ~/dockerfile/tomcat]# docker images
REPOSITORY                      TAG                 IMAGE ID            CREATED              SIZE
tomcat                          v1                  5f41fc206363        About a minute ago   424MB

启动tomcat 实例
[root@node01 ~/dockerfile/tomcat]# docker run -itd --name tomcat -p 8080:8080 tomcat:v1

访问验证
系统学devops系列: docker入门学习操作篇

7.企业级镜像仓库harbor

〉Habor是由VMWare公司开源的容器镜像仓库。事实上,Habor是在Docker Registry上进行了相应的
企业级扩展,从而获得了更加广泛的应用,这些新的企业级特性包括:管理用户界面,基于角色的访
问控制 ,AD/LDAP集成以及审计日志等,足以满足基本企业需求。

7.1 安装harbor

7.1.1 安装docker-compose

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

国内加速
sudo curl -L "https://get.daocloud.io/docker/compose/releases/download/1.24.1/docker-compose-(uname -s)-(uname -m)" -o /usr/local/bin/docker-compose

sudo chmod +x /usr/local/bin/docker-compose

[root@node01 ~]# docker-compose  -v
docker-compose version 1.23.1, build b02f1306

7.1.2 下载harbor离线包

 wget https://github.com/goharbor/harbor/releases/download/v1.10.1/harbor-offline-installer-v1.10.1.tgz

7.1.3 解压安装harbor

[root@node01 ~]# tar -xf harbor-offline-installer-v1.10.1.tgz

[root@node01 ~]# cd harbor
[root@node01 ~/harbor]# vim harbor.cfg

[root@node01 ~/harbor]# ./prepare
[root@node01 ~/harbor]# ./install.sh
安装完成,访问如图
系统学devops系列: docker入门学习操作篇

8.搭建使用私有docker registry

9.docker的系统资源限制及验证

10.docker compose

11.jenkins与docker的自动化ci/cd流水线实战

12.Docker 跨主机网络 overlay

系统学devops系列: docker入门学习操作篇

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin
avatar

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: