认识docker

认识Docker

文章目录

  • 认识Docker
    • 一、概览
    • 二、安装Docker
      • 2.1 配置镜像
    • 三、镜像
      • 3.1 镜像的命令
      • 3.2 将本地镜像推送到本地仓库
      • 3.3 `export/import`和`save/load`到区别
    • 三、容器
      • 3.1 启动容器 `docker container run`
      • 3.2 容器相关命令
      • 3.3 端口映射的案例
      • 3.4 将对一个容器的修改固定下来
    • 四、制作自己的镜像
      • 4.1 通过commit制作镜像
      • 4.2 通过Dockerfile制作镜像
        • (1)制作Dockerfile
        • (2) 创建镜像:`sudo docker build -t expres-demo .`
        • (3)根据镜像启动容器
        • (4) `RUN` 和`CMD`的区别
    • 五、数据盘
      • 5.1 volume 数据卷
        • (1)创建数据卷`sudo docker volume create nginx-logger`
        • (2)删除数据卷
      • 5.2 bind mount
        • (1)挂载到文件系统的任意目录
        • (2)指定数据盘容器
    • 六、网络
      • 6.1 `docker network` 相关命令
      • 6.2 docker网络的三种方式
        • (1) 使用桥接模式
        • (2) none
        • (3)host
      • 6.3 端口映射
      • 6.4 创建自定义网络
      • 6.5 连接到指定网络
      • 6.6 移除网络
    • 七、补充
      • 7.1 四层网络协议
      • 7.2 什么是编排,为什么需要编排?
    • 八、compose 组合
      • 8.1 安装compose
      • 8.2 docker-compose 相关命令
      • 8.3 编写第一个docker-compose.yml 示例,启动两个nginx
      • 8.4 配置数据卷和网络
    • 九、node项目
      • 9.1 服务分类
      • 9.2 目录结构
      • 9.3 安装配置

一、概览

客户端:Client , 给服务端下命令

后端: docker daemon, 服务干活

认识docker_第1张图片

  • docker pull 将镜像拉到本地

  • docker run 将镜像启动起来,变成一个容器

  • docker build 基于一个已有镜像,创建一个新的镜像

镜像是一个分层的文件结构:底层是操作系统

二、安装Docker

  • 官网链接

2.1 配置镜像

阿里云镜像

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://k8yv8apb.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

启动docker的几个命令:

sudo systemctl start docker
sudo systemctl stop docker
sudo systemctl restart docker
# 查看docker的版本
sudo docker version
sudo docker info

三、镜像

3.1 镜像的命令

  • sudo docker image ls 列出本地的所有镜像

    镜像的名称     标签       镜像ID         创建时间          大小
    REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
    hello-world   latest    bf756fb1ae65   13 months ago   13.3kB
    
  • sudo docker search hello-world 查询hello-world所有的docker镜像

    名称中,官方发布的可以省略/。可以通过网站看到一样的效果:https://hub.docker.com/search?q=hello-world&type=image

    名称   描述   星星数量    是否为官方版本     是否为自制的
    NAME                                       DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
    hello-world                                Hello World! (an example of minimal Dockeriz…   1379      [OK]       
    kitematic/hello-world-nginx                A light-weight nginx container that demonstr…   148                  
    tutum/hello-world                          Image to test docker deployments. Has Apache…   78                   [OK]
    dockercloud/hello-world                    Hello World!                                    19                   [OK]
    crccheck/hello-world                       Hello World web server in under 2.5 MB          14                   [OK]
    
  • sudo docker image history hello-world 查看镜像的历史版本

    告诉你这个镜像是怎么来的。

  • sudo docker image inspect hello-world 查看

    主要看RootFS,可以根据RootFS生成新的镜像

  • sudo docker image pull centos 拉取一个镜像

  • sudo docker pull centos:6 拉取centos的6版本

  • sudo docker image rmi d0957ffdf8a2 根据ID删除镜像

  • sudo docker image prune 移除未使用的镜像,没有被标记或补任何容器引用

  • sudo docker image tag centos lifei2021/centos7:latest 为镜像打标签

  • 其他命令:export、import、save、load、build

  • sudo docker export 将容器作为一个tar归档文件,导出到STDOUT

    sudo docker export -o centos.tar 1a3ae33bc215

  • sudo docker import将tar文件件导入为一个镜像

    # 删除所有容器
    sudo docker container rm $(sudo docker container ps -a -q)
    # 删除镜像
    sudo docker image rmi centos
    # 将tar文件导入为一个镜像
    sudo docker import centos.tar
    $ sudo docker image ls
    REPOSITORY          TAG       IMAGE ID       CREATED         SIZE
                      4396a1966268   6 seconds ago   209MB
    
  • sudo docker image prune 移除未使用镜像,没有标记或任何容器引用

    $ sudo docker image prune
    WARNING! This will remove all dangling images.
    Are you sure you want to continue? [y/N] y
    Deleted Images:
    deleted: sha256:4396a1966268778c5bdf5bb3298160e6393c3f03daff19d06e58121c799a8e67
    deleted: sha256:2b516442f14c95f4d69ab33d2789cf22d8d0b702bfee4aec868208896058a0a8
    
    Total reclaimed space: 209.3MB
    
  • sudo docker image save 把镜像保存为文件

    sudo docker image save -o hello-world.tar hello-world:latest
    
    # 将hello-world 镜像删除
    sudo docker image rmi hello-world
    
  • sudo docker image load -i 导入镜像

    $ sudo docker image load -i hello-world.tar
    9c27e219663c: Loading layer [==================================================>]  15.36kB/15.36kB
    Loaded image: hello-world:latest
    

3.2 将本地镜像推送到本地仓库

第一步:先登陆docker
parallels@hefrankeleyn:~$ sudo docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: lifei2021
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

parallels@hefrankeleyn:~$ sudo docker push lifei2021/centos7:latest
The push refers to repository [docker.io/lifei2021/centos7]
2653d992f4ef: Mounted from library/centos 
latest: digest: sha256:dbbacecc49b088458781c16f3775f2a2ec7521079034a7ba499c8b0bb7f86875 size: 529

3.3 export/importsave/load到区别

  • export导出容器到文件;
  • import把文件导入为镜像,可以指定文件和标签;
  • save把镜像到出为.tar文件;
  • load把.tar文件导入为镜像,不能修改名字和标签

三、容器

  • docker run命令会从image文件,生成一个正在运行的容器实例。
  • docker run命令具有自动抓取image文件的功能,如果发现本地没有指定image文件,会从仓库自动抓取;
  • image文件生成的容器实例,本身也是一个文件,称为容器文件
  • 关闭容器并不会删除容器文件
  • 一个容器的前台如果没有进程了,容器就会退出。

3.1 启动容器 docker container run

sudo docker container run hello-world

参数 含义
-i --interactive 交互式
-t --tty 分配一个伪终端
-d --detach 运行容器到后台
-a --attach list 附加到运行的容器
-e --env list 设置环境变量
-p --publish 发布容器端口到主机
–mount mount 挂载宿主机分区到容器
-v,–volum list
  • sudo docker container run -it centos /bin/bash 开始与centos容器进行交互

  • sudo docker container run -it hello-world /hello 另一个运行hello的方式

  • 演示传递一个参数:

    $ sudo docker container run -it  -e name="lifei2021" ubuntu
    root@21a800e86ebc:/# echo $name
    lifei2021
    
    

3.2 容器相关命令

  • sudo docker container ps 查看当前正在运行的容器

  • sudo docker container ps -a 查看所有的容器

    端口映射:将容器的端口映射为宿主机的端口。

    容器ID     镜像    运行命令    创建时间     状态    端口映射  容器的名字
    CONTAINER ID   IMAGE         COMMAND    CREATED        STATUS                    PORTS     NAMES
    95cae25a77d3   hello-world   "/hello"   4 hours ago    Exited (0) 4 hours ago              zen_dewdney
    4132593a4028   hello-world   "/hello"   20 hours ago   Exited (0) 20 hours ago             serene_galileo
    ffdbc233006a   hello-world   "/hello"   46 hours ago   Exited (0) 46 hours ago             festive_nash
    36e08c211eeb   hello-world   "/hello"   46 hours ago   Exited (0) 46 hours ago             boring_bouman
    
  • sudo docker container ls 查看当前正在运行的容器

  • sudo docker container ls -a 查看所有的容器

  • sudo docker container inspect <容器ID> 查看容器的详情

  • sudo docker ps -l 查看最近的容器

  • sudo docker container logs 1d31913717b2查看日志

  • sudo docker container top 7bb9df381666 查看容器的进程

  • sudo docker container port 7bb9df381666 查看端口映射

  • sudo docker container stop 7bb9df381666 停止容器(发送SIGTERM),终止,可以忽略

  • sudo docker container start 7bb9df381666 启动容器

  • sudo docker container rm 7bb9df381666 删除容器

  • sudo docker container ps -a -q 查看所有的容器ID

  • sudo docker container rm $(sudo docker ps -a -q) 删除所有容器

  • sudo docker commit -a"lifei2021" -m"add myroot.txt" 0de4a1652184 myroot:latest 将对一个容器的修改固定下来

  • sudo docker run -d -P nginx 在后台启动nginx容器,并把所有端口随机进行映射

    可以通过命令查看随机映射的端口:

    sudo docker container port ec4034a59192934c81f4b7864e6d58d306645ad160d8a38fcddb3828884dce1e

  • sudo docker container run -it -e name="lifei2021" ubuntu 传递一个参数

  • sudo docker container run -it --rm ubuntu 容器停止后,就自动删除

  • sudo docker container attach 4313fdd0817d 进入正在运行的容器,退出后会把容器也停了(过时,建议使用exec)

  • sudo docker container exec -it 3aed71d4d656 bash 进入一个正在运行的docker容器,执行命令

  • sudo docker container stats 3aed71d4d656 查看容器资源使用情况

  • sudo docker container update -m 500m --memory-swap -1 3aed71d4d656 更新一个或多个容器配置

  • sudo docker container kill 102fac87be89 终止容器(发送 SIGKILL),kill强制终止,不能忽略

  • sudo docker container cp f9642f6b780f:/u.txt ./ 将容器中的文件拷贝到本地

3.3 端口映射的案例

(1)将nginx服务映射为8080 ,并在前台运行

sudo docker container run -p 8080:80 nginx

# 将nginx服务映射为8080端口
$ sudo docker container run -p  8080:80 nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
a076a628af6f: Pull complete 
0732ab25fa22: Pull complete 
d7f36f6fe38f: Pull complete 
f72584a26f32: Pull complete 
7125e4df9063: Pull complete 
Digest: sha256:10b8cc432d56da8b61b070f4c7d2543a9ed17c2b23010b43af434fd40e2ca4aa
Status: Downloaded newer image for nginx:latest
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Configuration complete; ready for start up

# 查看端口映射的情况
$ sudo docker ps -l
[sudo] password for parallels: 
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                  NAMES
1d31913717b2   nginx     "/docker-entrypoint.…"   2 minutes ago   Up 2 minutes   0.0.0.0:8080->80/tcp   suspicious_tu

通过8080访问nginx:

$ curl http://10.211.55.4:8080



Welcome to nginx!



Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

(2)在后台运行

sudo docker container run -d -p 8080:80 nginx

$ sudo docker container run -d -p 8080:80 nginx
7bb9df3816665e996bc3979f399c46087bf263190718c451f6aa4cfd21d19c91

查看容器的进程:

$ sudo docker container top 7bb9df381666
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                4856                4833                0                   09:32               ?                   00:00:00            nginx: master process nginx -g daemon off;
systemd+            4917                4856                0                   09:32               ?                   00:00:00            nginx: worker process

nginx: master process nginx -g daemon off;

-g daemon off 不要后台运行。容器启动之后,如果没有前台运行的东西,就退出去了。

3.4 将对一个容器的修改固定下来

$ sudo docker commit -a"lifei2021" -m"add myroot.txt" 0de4a1652184 myroot:latest
sha256:4be2e6ff3f952dff583015453d45fdbc2c58f92c8a289f1ec51ed568bd128930
$ sudo docker image ls
REPOSITORY          TAG       IMAGE ID       CREATED          SIZE
myroot              latest    4be2e6ff3f95   52 seconds ago   72.9MB

固定下来的镜像比原来镜像RootFS的Layers多一层:

四、制作自己的镜像

4.1 通过commit制作镜像

把容器变成镜像

$ sudo docker container commit -m"我自己的dream镜像" -a"lifei2021" ba37ba3a32c9 lifei2021/myubuntu:v1
sha256:3cd254306a78c03239b5b62d0255d83bb416830495f97c429ec7d749172cbe90
sudo docker image ls
REPOSITORY           TAG       IMAGE ID       CREATED          SIZE
lifei2021/myubuntu   v1        3cd254306a78   10 seconds ago   72.9MB

# 使用自定义过的镜像创建容器
$ sudo docker container run -it 3cd254306a78 
root@d0ec73082b63:/# cd /root/
root@d0ec73082b63:~# ll
total 24
drwx------ 1 root root 4096 Feb 13 10:02 ./
drwxr-xr-x 1 root root 4096 Feb 13 10:07 ../
-rw------- 1 root root   40 Feb 13 10:02 .bash_history
-rw-r--r-- 1 root root 3106 Dec  5  2019 .bashrc
-rw-r--r-- 1 root root  161 Dec  5  2019 .profile
-rw-r--r-- 1 root root    0 Feb 13 10:02 dream.

4.2 通过Dockerfile制作镜像

(1)制作Dockerfile
命令 含义 示例
FROM 继承的镜像 FROM node
COPY 拷贝 COPY ./app /app
WORKDIR 指定工作目录 WORKDIR /app
RUN 编译阶段运行命令 RUN npm install
EXPOSE 暴露端口 EXPOSE 3000
CMD 容器运行阶段运行的命令 CMD npm start

安装node:

sudo apt install npm
# n 模块是用来安装各种版本的 node 的一个工具。参数 -g 表示全局安装
sudo npm install n -g
# 安装最长期支持的node
sudo n lts
# 检测node
node -v

# 安装express项目生成器
sudo npm install express-generator -g

# 生成一个项目的脚手架

dockerignore

$ cat .dockerignore 
.git
node_modules

Dockerfile (第一个版本,没有CMD)

$ cat Dockerfile 
FROM node
COPY ./app /app
WORKDIR /app
RUN npm install --registry=https://registry.npm.taobao.org
EXPOSE 3000

创建一个带有可以ping的nginx

FROM nginx
RUN apt update
RUN apt install -y inetutils-ping
RUN apt install -y dnsutils
RUN apt install -y net-tools
RUN apt install -y iproute2
RUN apt install -y curl
EXPOSE 80

说明:

# ping
apt install -y inetutils-ping
# nslookup
apt install -y dnsutils
# ifconfig
apt install -y net-tools
# ip
apt install -y iproute2
# curl
apt install -y curl
(2) 创建镜像:sudo docker build -t expres-demo .
~/nodeapp$ sudo docker build -t expres-demo .
Sending build context to Docker daemon  7.005MB
Step 1/5 : FROM node
 ---> d6740064592f
Step 2/5 : COPY ./app /app
 ---> 0b464a2c44f2
Step 3/5 : WORKDIR /app
 ---> Running in 8187c11e8ab0
Removing intermediate container 8187c11e8ab0
 ---> 91df454d2726
Step 4/5 : RUN npm install   --registry=https://registry.npm.taobao.org
 ---> Running in 0adf0c59d038

up to date in 1s
npm notice 
npm notice New minor version of npm available! 7.3.0 -> 7.5.4
npm notice Changelog: 
npm notice Run `npm install -g [email protected]` to update!
npm notice 
Removing intermediate container 0adf0c59d038
 ---> 2e19600ac139
Step 5/5 : EXPOSE 3000
 ---> Running in 28e776587cca
Removing intermediate container 28e776587cca
 ---> ba433c10c5df
Successfully built ba433c10c5df
Successfully tagged expres-demo:latest
(3)根据镜像启动容器
$ sudo docker container run -it -p 8080:3000 ba433c10c5df /bin/bash
root@d376fbc884b0:/app# npm start

> [email protected] start
> node ./bin/www

GET / 200 159.337 ms - 170
GET / 200 11.691 ms - 170

curl http://10.211.55.4:8080

Dockerfile (第二个版本,带CMD)

$ cat Dockerfile 
FROM node
COPY ./app /app
WORKDIR /app
RUN npm install   --registry=https://registry.npm.taobao.org
EXPOSE 3000
CMD npm start

重新编译:

$ sudo docker build -t express-demo .

$ sudo docker container run -it -p 8080:3000 1424ecc80a3d

> [email protected] start
> node ./bin/www

GET / 200 153.572 ms - 170

curl http://10.211.55.4:8080

还可以在后台启动:

sudo docker container run -d -it -p 8080:3000 1424ecc80a3d

(4) RUNCMD的区别

运行阶段不同:

  • run 编译镜像阶段时执行;
  • CMD 当启动容器的时候执行;

在Dockerfile文件中:

  • run在Dockerfile中可以写多条;
  • CMD在Dockerfile中只能有一条;
  • 而且CMD时默认命令

五、数据盘

删除容器的时候,容器的文件也会被删除掉。

5.1 volume 数据卷

指向文件系统的一个docker区域。

  • volumes 是宿主机的一部分(/var/lib/docker/volumes)
$ sudo docker volume --help

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
(1)创建数据卷sudo docker volume create nginx-logger
$ sudo docker volume create  nginx-logger
nginx-logger
$ sudo docker volume ls 
DRIVER    VOLUME NAME
local     nginx-logger

$ sudo docker volume inspect nginx-logger
[
    {
        "CreatedAt": "2021-02-15T13:45:21+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/nginx-logger/_data",
        "Name": "nginx-logger",
        "Options": {},
        "Scope": "local"
    }
]

$ sudo docker volume create nginx-html
nginx-html

使用挂载(方式一):

sudo docker container run -d --name nginx1 --mount src=nginx-html,dst=/usr/share/nginx/html nginx

$ sudo ls -l /var/lib/docker/volumes/nginx-html/_data
total 8
-rw-r--r-- 1 root root 494 Dec 15 21:59 50x.html
-rw-r--r-- 1 root root 612 Dec 15 21:59 index.html

使用挂载(方式二):

sudo docker container run -d --name nginx2 -v nginx-html:/usr/share/nginx/html nginx

$ sudo docker exec -it 44c2be294302d2cd4c186641e0098b0fd609072c3dfe47dac9cc7e2994bdcf44 /bin/bash
root@44c2be294302:/# ls /usr/share/nginx/html/
404.html  50x.html  index.html
(2)删除数据卷

查看没有任何容器引用的数据卷:docker volume ls -f dangling=true

$ sudo docker volume ls -f dangling=true
DRIVER    VOLUME NAME
local     nginx-html
local     nginx-logger

删除数据卷:

sudo docker volume rm nginx-logger

一次性将未被容器引用的数据卷都删光:

sudo docker volume prune

$ sudo docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
nginx-html

Total reclaimed space: 1.106kB

5.2 bind mount

(1)挂载到文件系统的任意目录

指向文件系统

  • 此方式与Linux系统的mount方式相似,即是会覆盖容器内已存在的目录或文件,但不会改变容器内原有的文件,当umount 后容器内原有的文件就会还原;
  • 创建容器的时候,可以通过 -v 或 --volumn 给它指定一下数据盘;
  • bind mounts 可以存储在宿主机的任何位置;
  • 如果源文件目录不存在,不会自动创建,会抛出一个错误;
  • 如果挂载目标在容器中非空目录,则该目录现有内容将被隐藏;

挂载命令:

sudo docker container run -v /mnt:/mnt -it --name logs centos bash

查看容器详细信息:

sudo docker container inspect logs

宿主机的目录可以和容器目录不一样:

(2)指定数据盘容器

第一步:创建数据盘容器

sudo docker container create -v /logger:/logger --name logger centos

docker container createdocker contaienr run的区别:

`docker container create` 只创建容器,不执行;
`docker container run` 创建并执行容器

第二步:继承挂载

sudo docker container run --volumes-from logger --name logger1 -it centos bash

sudo docker container run --volumes-from logger --name logger2 -it centos bash

六、网络

6.1 docker network 相关命令

  • docker network ls 列出所有网络

    $ sudo docker network ls
    NETWORK ID     NAME      DRIVER    SCOPE
    79cf664cff4a   bridge    bridge    local
    2c9bbbe0934f   host      host      local
    8b3fbc2eb5db   none      null      local
    
  • docker network inspect bridge 查看桥接模式中连接了哪些容器

    "IPv4Address": "172.17.0.2/16"
    16 两个8,代表前两位的子网掩码
    
  • docker network inspect none 查看null中连接了哪些容器

  • docker network create --driver bridge finance_web 创建桥接类型的网络

  • sudo docker network connect dev_web no_nginx 将no_nginx 容器添加到dev_web 网络内

6.2 docker网络的三种方式

安装Docker时,它会自动创建三个网络,birdge(创建容器默认链接到此网络)、none、host

(1) host : 会复用宿主机的IP;容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口;

(2) birdge (默认) : 桥接模式,docker容器也有自己的ip地址(为每一个容器分配一个IP);

(3)null:该模式关闭了容器的网络功能,对外界完全隔离;

可以使用--network标志来指定容器应连接到哪些网络。

补充:

yum 是 redhat、centos 提供的工具;
apt-get 是ubuntu 的工具

说明:提前通过Dockerfile,制作了自定义的镜像nginx-with-ping:

# 第一步:Dockerfile 文件内容
FROM nginx
RUN apt update
RUN apt install -y inetutils-ping
RUN apt install -y dnsutils
RUN apt install -y net-tools
RUN apt install -y iproute2
RUN apt install -y curl
EXPOSE 80

# 第二步:生成自定义镜像 (. 代表当前目录。Dockerfile位于当前目录)
sudo docker build -t nginx-with-ping .
(1) 使用桥接模式

ping依赖安装好之后,可以通过 ip访问

sudo docker container run -d --name nginx1 nginx-with-ping
sudo docker container run -d --name nginx2 nginx-with-ping

通过加一个参数,就可以通过容器名来ping通

sudo docker container run -d --name nginx3 --link nginx1 nginx-with-ping

原理是其在/etc/hosts文件中关联了nginx1的ip

# 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	nginx1 56ff67b4a6ec
172.17.0.4	9877a70506b8
(2) none

none模式使用--net none指定:

sudo docker container run -d --name nginx_none --net none nginx-with-ping

$ sudo docker exec -it nginx_none bash
root@f8938e6712e8:/# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
ping: sending packet: Network is unreachable

$ sudo docker exec -it nginx_none bash
root@f8938e6712e8:/# ip addr
1: lo:  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

查看none相关的容器

sudo docker network inspect none

(3)host

sudo docker container run -d --name nginx_host --net host nginx-with-ping

在mac的ubuntu 虚拟机中,使用host网络启动容器后,容器刚启动就被停掉了。暂时不知道原因。

6.3 端口映射

(1)随机映射端口:

sudo docker container run -d --name nginx_port1 -p 80 nginx-with-ping

$ sudo docker container run -d --name nginx_port1 -p 80 nginx-with-ping
4918e34fd09980fed098893a0b8177790d2cf0dbf183afd2e9aef2b8b4498768
parallels@hefrankeleyn:~$ sudo docker container port nginx_port1
80/tcp -> 0.0.0.0:49153

(2)开发容器的所有端口-P--publish-all

sudo docker container run -d --name nginx_port_all -P nginx-with-ping

sudo docker container run -d --name nginx_port_all2 --publish-all nginx-with-ping

$ sudo docker container run -d --name nginx_port_all2 --publish-all nginx-with-ping
bf99b05095f303d29be2d0baed6abb97cd24c78eb51a51ea30756d72f610d562
parallels@hefrankeleyn:~$ sudo docker container port nginx_port_all2
80/tcp -> 0.0.0.0:49155

6.4 创建自定义网络

sudo docker network create --driver bridge finance_web

$ sudo docker network create --driver bridge finance_web
3a04609afb346b0b3833aa509d9cfbc2d9be4715644d5fcbd2716fbf7f020c46
parallels@hefrankeleyn:~$ sudo docker network create --driver bridge dev_web
a682b63bb6148d1f59892f105eacb9aaca96ae6f8f3c7cd1259eae0246131a4a
parallels@hefrankeleyn:~$ sudo docker network ls
NETWORK ID     NAME          DRIVER    SCOPE
e5a11bd477b0   bridge        bridge    local
a682b63bb614   dev_web       bridge    local
3a04609afb34   finance_web   bridge    local
2c9bbbe0934f   host          host      local
8b3fbc2eb5db   none          null      local

使用自定义的网络:

sudo docker container run -d --name nginx_dev_web1 --net dev_web nginx-with-ping

sudo docker container run -d --name nginx_dev_web2 --net dev_web nginx-with-ping

sudo docker container run -d --name nginx_finace_web1 --net finance_web nginx-with-ping

sudo docker container run -d --name nginx_finace_web2 --net finance_web nginx-with-ping

此时dev_web 网络下的容器间也可以互相访问;finance_web 网络下的容器间可以互相访问。

  • 自定义网络的好处:自定义网络内部会自带一个DNS服务器,让你可以通过容器的名字和ID来访问对应的容器。

    $ sudo docker exec -it nginx_dev_web1 bash
    root@52251fd310c3:/# ping nginx_dev_web2
    PING nginx_dev_web2 (172.19.0.3): 56 data bytes
    64 bytes from 172.19.0.3: icmp_seq=0 ttl=64 time=0.086 ms
    64 bytes from 172.19.0.3: icmp_seq=1 ttl=64 time=0.251 ms
    
  • 不同自定网络的容器不能互相访问:实现的原理是,通过子网掩码划分网段(例如: 172.18.0.2/16)

6.5 连接到指定网络

让已经存在的网络,指向已存在的网络。

示例:创建一个容器,不指定网络

-- 创建一个没有指定网络的容器
sudo docker container run -d --name no_nginx nginx-with-ping

该网络的ID地址为:
            "8bdd2dd1f3785c2c263863efd623c7172112e22f42f53664b0b0ab08133d6fb9": {
                "Name": "no_nginx",
                "EndpointID": "e1667c6ee074a98c0f2fddd49b2a6edffd7a7d0bc5f2c5ceeb17527ce482e14f",
                "MacAddress": "02:42:ac:11:00:08",
                "IPv4Address": "172.17.0.8/16",
                "IPv6Address": ""
            },

此时该IP不能访问dev_web 网络下的容器。可以把这个容器添加到这个网络那,这样就能访问dev_web下的容器:

sudo docker network connect dev_web no_nginx

之后就能正常访问:

$ sudo docker exec -it no_nginx bash
root@8bdd2dd1f378:/# ping nginx_dev_web1
PING nginx_dev_web1 (172.19.0.2): 56 data bytes
64 bytes from 172.19.0.2: icmp_seq=0 ttl=64 time=0.117 ms
64 bytes from 172.19.0.2: icmp_seq=1 ttl=64 time=0.116 ms

此时相当于给no_nginx 安装了两块网卡,能够同时连接到默认网络和dev_web 网络。

"8bdd2dd1f3785c2c263863efd623c7172112e22f42f53664b0b0ab08133d6fb9": {
                "Name": "no_nginx",
                "EndpointID": "32df7232578b6cf01831e47ff3e1ab8ad4b82e4e76d850b27e97fd66df948c59",
                "MacAddress": "02:42:ac:13:00:04",
                "IPv4Address": "172.19.0.4/16",
                "IPv6Address": ""
            },

6.6 移除网络

sudo docker network rm myweb

七、补充

7.1 四层网络协议

  • 第一层:应用层, 进行业务处理。对应具体到文本信息;http、ftp
  • 第二层:传输层,tcp/udp。端口号是传输层的一部分
  • 第三层:网络层,ip地址
  • 第四层:物理层,mac地址、二进制信号

7.2 什么是编排,为什么需要编排?

什么是编排,为什么需要编排?

  1. 考虑选择哪些镜像;
  2. 按照合适的顺序启动容器;
  3. 管理容器中的服务;
  4. 如果服务宕机了还需要负责重启;
  5. 如果服务器负载太大,需要动态扩容;
  6. 如果程序更新了,还需要动态升级镜像和服务;

上面这些步骤,人工做很麻烦,逐渐出现了工具:docker-compose、k8s。

目前k8s已经胜出了。

八、compose 组合

compose通过一个配置文件来管理多个docker容器。

每个服务都对应一个镜像,对应一个或多个容器;

  • 在配置文件中,所有容器通过services来定义,然后使用docker-compose脚本启动、停止和重启应用中的服务以及所有依赖服务的容器。
  • 步骤:
    • 运行docker-compose up,compose 将启动并运行整个应用程序(配置文件组成)
    • services可以定义需要的服务,每个服务都有自己的名字、使用的镜像、挂载的数据卷所属的网络和依赖的其他服务;
    • networks是应用的网络,在它下面可以定义使用的网络名称、类型;
    • volumes是数据卷,可以在此定义数据卷,然后挂载到不同的服务上面使用;

8.1 安装compose

centos:

yum install -y epel-release
yum install -y python-pip
pip install docker-compose

ubuntu:

sudo apt install python3-pip
sudo pip3 install docker-compose
$ docker-compose -v
docker-compose version 1.28.2, build unknown

8.2 docker-compose 相关命令

  • docker-compose up 启动,执行这个命令的时候会向当前目录下找docker-compose.yml文件
  • docker-compose up -d 后台启动
  • docker-compose up --build 启动并重新编译
  • docker-compose ps 打印当前启动的容器
  • docker-compose stop 停止容器
  • docker-compose start 启动容器
  • docker-compose logs -f 查看容器的日志
  • docker-compose down 停止并删除容器,并删除创建的网络

8.3 编写第一个docker-compose.yml 示例,启动两个nginx

$ cat docker-compose.yml 
version: "2"
# 服务
services:
        nginx1:
                image: nginx
                ports:
                        - "8081:80"
        nginx2:
                image: nginx
                ports:
                        - "8082:80"

在前台启动:

sudo docker-compose up

在后台启动:

sudo docker-compose up -d

打印当前启动的容器:

$ sudo docker-compose ps
       Name                     Command               State          Ports        
----------------------------------------------------------------------------------
nginxdemo_nginx1_1   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:8081->80/tcp
nginxdemo_nginx2_1   /docker-entrypoint.sh ngin ...   Up      0.0.0.0:8082->80/tcp

停止容器:

sudo docker-compose stop

启动容器:

sudo docker-compose start

查看容器的日志:

sudo docker-compose logs -f

进入一个容器

sudo docker container exec -it nginxdemo_nginx1_1 bash

停止并删除容器,并删除创建的网络

$ sudo docker-compose down
Stopping nginxdemo_nginx2_1 ... done
Stopping nginxdemo_nginx1_1 ... done
Removing nginxdemo_nginx2_1 ... done
Removing nginxdemo_nginx1_1 ... done
Removing network nginxdemo_default

8.4 配置数据卷和网络

  • networks 指定自定义网络
  • volumes 指定数据卷
  • 数据卷在宿主机的位置:/var/lib/docker/volumes/
$ cat docker-compose.yml 
version: "2"
# 服务
services:
        nginx1:
                image: nginx
                volumes:
                        - "./front:/usr/share/nginx/html"
                ports:
                        - "8081:80"
        nginx2:
                image: nginx
                volumes:
                        - "./backend:/usr/share/nginx/html"
                ports:
                        - "8082:80"

创建一个本地的数据卷。

$ cat docker-compose.yml 
version: "2"
# 服务
services:
        nginx1:
                image: nginx
                volumes:
                        - "mydata:/data"
                        - "./front:/usr/share/nginx/html"
                ports:
                        - "8081:80"
        nginx2:
                image: nginx
                volumes:
                        - "mydata:/data"
                        - "./backend:/usr/share/nginx/html"
                ports:
                        - "8082:80"
volumes:
        mydata:
                driver: local

进入容器创建文件:

$ sudo docker container exec -it nginxwebserver_nginx2_1 bash
root@9e993935d039:/# cd /data/
root@9e993935d039:/data# ls
1.txt
root@9e993935d039:/data# touch 2.txt

宿主机目录:

$ ll /var/lib/docker/volumes/nginxwebserver_mydata/_data
total 8
drwxr-xr-x 2 root root 4096 Feb 17 20:07 ./
drwx-----x 3 root root 4096 Feb 17 20:06 ../
-rw-r--r-- 1 root root    0 Feb 17 20:06 1.txt
-rw-r--r-- 1 root root    0 Feb 17 20:07 2.txt

可以通过命令查看映射信息:

sudo docker container inspect nginxwebserver_nginx2_1

配置网络:

$ cat docker-compose.yml 
version: "2"
# 服务
services:
        nginx1:
                image: nginx
                volumes:
                        - "mydata:/data"
                        - "./front:/usr/share/nginx/html"
                networks:
                        - "myweb"
                        - "default"
                ports:
                        - "8081:80"
        nginx2:
                image: nginx
                volumes:
                        - "mydata:/data"
                        - "./backend:/usr/share/nginx/html"
                networks:
                        - "myweb"
                        - "default"
                ports:
                        - "8082:80"
volumes:
        mydata:
                driver: local
networks:
        myweb:
                driver: bridge

九、node项目

9.1 服务分类

  • db: 使用mariadb作为应用的数据库
  • node: 启动node服务
  • web: 使用nginx作为应用的web服务器

9.2 目录结构

文件 说明
docker-compose.yml 定义本地开发环境所需要的服务
image/node node项目
image/nginx 放nginx的配置

https://www.npmjs.com/package/typescript

├── docker-compose.yml
└── images
    ├── nginx
    │   └── conf.d
    │       └── default.conf
    └── node
        ├── Dockerfile
        └── web
            ├── package.json
            ├── package-lock.json
            ├── public
            │   └── index.html
            └── server.js

9.3 安装配置

(1)创建目录,初始化node项目

-- 创建目录卷
mkdir images/node/web
-- 进入目录
cd images/node/web
-- 初始化项目
npm init -y
-- 安装mysql依赖
npm install mysql -S
-- 修改 package.json

(2)修改package.json

$ cat package.json 
{
  "name": "web",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node server.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "mysql": "^2.18.1"
  }
}

(3)创建Dockerfile文件

images/node$ cat Dockerfile 
FROM node
MAINTAINER lifei2021
COPY ./web /web
WORKDIR /web
RUN npm install --registry=https://registry.npm.taobao.org
CMD npm start

(4)编辑docker-compose.yml 文件

$ cat docker-compose.yml 
version: "2"
services:
        db:
                image: mariadb
                # 指定环境变量
                environment:
                        MYSQL_ROOT_PASSWORD: "123456"
                        MYSQL_DATABASE: my_node_db
                        MYSQL_USER: oneUser
                        MYSQL_PASSWORD: 123456
                volumes:
                        - "mydbdata:/var/lib/mysql"
        node:
                build:
                        # 指定上下文
                        context: "./images/node"
                        # 指定dockerfile文件
                        dockerfile: Dockerfile
                depends_on:
                        - db 
        web:
                image: nginx
                ports:
                        - "8080:80"
                volumes:
                        - "./images/nginx/conf.d:/etc/nginx/conf.d"
                        - "./images/node/web/public:/public"
                depends_on:
                        node
volumes:
        mydbdata:
                driver: local

(5) 编写nginx配置文件

images/nginx/conf.d$ cat default.conf 
server {
  listen 80;
  server_name localhost 10.211.55.4;
  location / {
    root /public;
    index index.html;
  }

  location /api {
    proxy_pass http://node:3000;
  }
}

(6) 启动

sudo docker-compose up --build

$ curl http://localhost:8080/
index.html
parallels@hefrankeleyn:~$ curl http://localhost:8080/api
solution: 2parallels@hefrankeleyn:~$ 

你可能感兴趣的:(Docker,docker)