一、什么是Docker

1.1 Docker简介

Docker是一个能够把开发的应用程序自动部署到容器的开源引擎

这里列举了一些docker的资源网站:

1.1.1 Docker的核心组件

  • Docker客户端和服务器;
  • Docker 镜像;
  • Registry;
  • Docker 容器

Docker客户端和服务器
Docker是一个客户-服务器(C/S)架构的程序。Docker客户端只需向Docker服务器或 守护进程发出请求,服务器或守护进程将完成所有工作并返回结果。

在这里插入图片描述

Docker镜像
用于基于镜像来运行自己的容器

Registry
Docker用Registry来保存用户构建的镜像。Registry分为公共和私有两种。Docker公司 运营的公共Registry叫做Docker Hub。用户可以在Docker Hub,分享并保存自己的镜像。

容器
Docker可以帮你构建和部署容器,你只需要把自己的应用程序或服务打包放进容器即可。

1.1.2 Docker的作用

  • 加速本地开发和构建流程,使其更加高效、更加轻量化。本地开发人员可以构建、 运行并分享Docker容器。容器可以在开发环境中构建,然后轻松地提交到测试环境 中,并最终进入生产环境。
  • 能够让独立服务或应用程序在不同的环境中,得到相同的运行结果。这一点在面向 服务的架构和重度依赖微型服务的部署中尤其实用。
  • 用Docker创建隔离的环境来进行测试。例如,用Jenkins CI这样的持续集成工具启 动一个用于测试的容器。
  • Docker可以让开发者先在本机上构建一个复杂的程序或架构来进行测试,而不是一 开始就在生产环境部署、测试。
  • 构建一个多用户的平台即服务(PaaS)基础设施。
  • 为开发、测试提供一个轻量级的独立沙盒环境,或者将独立的沙盒环境用于技术教 学,如Unix shell的使用、编程语言教学。

1.1.3 Docker的特性

Docker可运行在任何安装了现代Linux内核的x64主机上,得益于Linux内核的namespace,用于隔离文件系统、进程和网络

  • 文件系统隔离:每个容器都有自己的root文件系统。
  • 进程隔离:每个容器都运行在自己的进程环境中。
  • 网络隔离:容器间的虚拟网络接口和IP地址都是分开的。
  • 资源隔离和分组:使用cgroups® (即control group, Linux的内核特性之一)将CPU 和内存之类的资源独立分配给每个Docker容器。
  • 写时复制:文件系统都是通过写时复制创建的,这就意味着文件系统是分层的、快速的,而且占用的磁盘空间更小。

1.2 Docker守护进程

安装完Docker后【见2.1】,我们需要确认Docker的守护进程是否运行。Docker以root权限运行它的守护进程,来处理普通用户无法完成的操作(如挂载文件系统)。docker程序是 Docker守护进程的客户端程序,同样也需要以root身份运行。
当Docker安装完毕后,默认会立即启动Docker守护进程。守护进程监听/var/run/docker.sock这个unix套接字文件,来获取来自客户端的Docker请求。

二、Docker的使用

2.1 基本操作

安装

sudo apt-get install docker
sudo apt install docker.io

### 拉取镜像
```bash
sudo docker pull ubuntu:latest

查看所有镜像(images)

sudo docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
busybox      latest    ffe9d497c324   5 days ago    1.24MB
ubuntu       latest    ba6acccedd29   8 weeks ago   72.8MB

删除镜像(rmi)

sudo docker image rm [image]
# 或者
sudo docker rmi [image]
  • -f:强制删除,即使有容器在引用
    建议先删除容器、再删除镜像

创建容器(挂载、后台、映射、网络)(run)

  • d:后台运行
  • v:挂载
  • net:指明网络
  • 容器名称:Mydocker
  • privileged:赋予拓展权限
  • 宿主机挂载目录:/home/zhuchun/docker_volume
  • 容器挂载目录:/master
sudo docker run -t -i -d --name Mydocker --net=none --privileged -v /home/zhuchun/docker_volume:/master ubuntu /bin/bash
2caf5bac0bca3491cd0c528a81869e296cad1e9a4af626fe71e74b488ea8f4ff

查看端口是否占用:netstat -nultp | grep port_number,然后映射端口:

-p选项可以让我们灵活地管理容器和宿主机之间的映射关系,可以指定将容器中的端口映射到Docker宿主机的某一特定端口上

# 绑定端口
sudo docker run -d -p 80:80 --name MyPortDocker ubuntu /bin/bash
# 绑定ip和端口
sudo docker run -d -p 127.0.0.1:80:80 --name MyPortDocker ubuntu /bin/bash
# 绑定ip的随机端口
sudo docker run -d -p 127.0.0.1::80 --name MyPortDocker ubuntu /bin/bash

查看容器端口映射情况:sudo docker port MyPortDocker 80这个端口需要被引用,否则会报错

查看运行的容器(ps)

sudo docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED        STATUS        PORTS     NAMES
2caf5bac0bca   ubuntu    "/bin/bash"   15 hours ago   Up 15 hours             Mydocker
# 打开已有容器
sudo docker start Mydocker
# 停止运行容器
sudo docker stop Mydocker
# 重启容器
sudo docker restart Mydocker

进入容器(exec)

exec实际是在容器内部额外启动新进程

sudo docker exec -it Mydocker /bin/bash

删除容器(rm -f)

sudo docker rm -f Mydocker

清理掉所有处于终止状态的容器

sudo docker container prune

2.2进阶操作

查看容器信息(inspect)

sudo docker inspect Mydocker
[
    {
        "Id": "b893f994a06147f6e4f91ec78a4d0392f3f1ffacafaadeb6d32ead67dcdfc95b",
        "Created": "2021-12-14T01:16:06.686964077Z",
        "Path": "/bin/bash",
        "Args": [],
...

查看容器进程(top)

sudo docker top Mydocker

构建镜像——建议使用Dockerfile来构建镜像

这是已经安装好ping命令的容器,配置见3.1

CONTAINER ID   IMAGE     COMMAND       CREATED        STATUS        PORTS     NAMES
b893f994a061   ubuntu    "/bin/bash"   31 hours ago   Up 23 hours             Mydocker

使用commit构建:sudo docker commit -m "ping ok" --author="Chun" Mydocker chun/net:ping
适用于原有的容器的保存

REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
chun/net     ping      5194404721d7   13 seconds ago   174MB
ubuntu       latest    ba6acccedd29   2 months ago     72.8MB

我们的第一个Dockerfile
创建一个文件:sudo vi docker_file_first

# Version: 0.0.1
# 设置新镜像的基础镜像ubuntu:21.10
From ubuntu:21.10
# 添加自己的详细信息
MAINTAINER Chun '2857111062@qq.com'
# Run会运行随后跟的命令,以便于验证容器功能
RUN apt update
# 安装vim
RUN apt install -y  vim
# # 安装ping , -y指的是同意安装,如果不加-y它就会等待你来输入Y/N
RUN apt install -y inetutils-ping
# # 安装net-tools
RUN apt install -y net-tools
RUN ifconfig
RUN echo 'Hi, Net!' > init.txt
RUN cat init.txt
# EXPOSE 告诉容器内的应用程序将会使用容器的指定端口号
EXPOSE 80

复制一份,名称改为Dockerfile,因为构建镜像实际上是去找Dockerfile这个文件,我这里命名以便于保存:cp docker_file_first Dockerfile

  • -t:指定仓库和tag
  • -f:指定Dockerfile目录
    使用dockerfile构建新镜像:sudo docker build -t="chun/net:ifconfig" .

TODO:网络无法连通->docker网络配置,已解决,重启docker,service docker restart

REPOSITORY   TAG        IMAGE ID       CREATED         SIZE
chun/net     ifconfig   e45da4d16b65   8 seconds ago   176MB

创建Docker账号和登录Docker(login)

在Docker Hub上创建一个账户

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: 2857xxxxxx
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

查看镜像创建的每一层 (history)

$ sudo docker history chun/net:ifconfig

IMAGE          CREATED       CREATED BY                                      SIZE      COMMENT
e45da4d16b65   5 days ago    /bin/sh -c #(nop)  EXPOSE 80                    0B        
dc7789a0583b   5 days ago    /bin/sh -c cat init.txt                         0B        
c15b8a9381ee   5 days ago    /bin/sh -c echo 'Hi, Net!' > init.txt           9B        
89129e1ecad1   5 days ago    /bin/sh -c ifconfig                             0B        
280c4a7d7c8e   5 days ago    /bin/sh -c apt install -y net-tools             1.81MB    
edd629d43046   5 days ago    /bin/sh -c apt install -y inetutils-ping        1.41MB    
f9e07c25853f   5 days ago    /bin/sh -c apt install -y  vim                  62.6MB    
1aacc1708baf   5 days ago    /bin/sh -c apt update                           32.4MB    
ce03a693f185   5 days ago    /bin/sh -c #(nop)  MAINTAINER Chun '28571110…   0B        
2dc51e04d744   6 weeks ago   /bin/sh -c #(nop)  CMD ["bash"]                 0B        
<missing>      6 weeks ago   /bin/sh -c #(nop) ADD file:c061cabbaa10b98ee…   77.4MB    

运行自己的Docker Registry

安装运行一个Registry应用的容器,并绑定到宿主机5000端口:
sudo docker run -p 5000:5000 registry

将上传的镜像打好标签:

sudo docker tag chun/net:ifconfig 127.0.0.1:5000/chun/net

把dockerfile构建好的镜像上传至新的Registry目的地址:

sudo docker push 127.0.0.1:5000/chun/net

问题:Get http://127.0.0.1:5000/v2/: net/http: request canceled (Client.Timeout exceeded while awaiting headers)
待解决…

链接两个容器(Link)

docker run --link可以用来链接2个容器,使得源容器(被链接的容器)和接收容器(主动去链接的容器)之间可以互相通信
源容器:

sudo docker run -d -it --name MyLinked ubuntu

接收容器:
MyLinked:ml
源容器 : 源容器别名

sudo docker run -d -it --name MyLink --link MyLinked:ml chun/net:ifconfig

现在,我们进入MyLink容器,去看是否能通过容器名ping通源容器

sudo docker exec -it MyLink /bin/bash

root@d3ee8d011005:/# ping ml
PING ml (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=0.433 ms
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.088 ms

三、容器的配置

3.1 简单的配置

创建与宿主机相同网络的容器:

sudo docker run -t -i -d --name Mydocker --net=host --privileged -v /home/zhuchun/docker_volume:/master ubuntu /bin/bash

只要宿主机网络正常,apt update可以直接运行

# apt和apt-get区别不是很大,但建议使用apt
# 更新apt
apt update
# 安装vim
apt install vim
# 安装ping
apt install inetutils-ping
# 安装net-tools
apt install net-tools

查看网络:

ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.xx.xxx  netmask 255.255.255.0  broadcast 192.168.xx.xxx
        inet6 fe80::9c8c:82fa:5d81:6414  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:xx:00:xx  txqueuelen 1000  (Ethernet)
        RX packets 294786  bytes 64275392 (64.2 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 476322  bytes 101042173 (101.0 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

3.2不简单的配置——openswitch,vlan划分

我们将使用dockerfile构建的这个镜像来进行一个vlan的划分,如何构建镜像——>2.2构建镜像

查看我们的镜像sudo docker images

REPOSITORY   TAG        IMAGE ID       CREATED        SIZE
chun/net     ifconfig   e45da4d16b65   6 hours ago    176MB

创建三个docker容器,分别是RouterA、RouterB、RouterC,看不懂见——>2.1 创建容器

sudo docker run -t -i -d --name RouterA --net=none --privileged -v /home/zhuchun/docker_volume:/master chun/net:ifconfig /bin/bash
sudo docker run -t -i -d --name RouterB --net=none --privileged -v /home/zhuchun/docker_volume:/master chun/net:ifconfig /bin/bash
sudo docker run -t -i -d --name RouterC --net=none --privileged -v /home/zhuchun/docker_volume:/master chun/net:ifconfig /bin/bash
CONTAINER ID   IMAGE               COMMAND       CREATED              STATUS              PORTS     NAMES
2e78535122aa   chun/net:ifconfig   "/bin/bash"   About a minute ago   Up About a minute             RouterC
a3a04a31c297   chun/net:ifconfig   "/bin/bash"   About a minute ago   Up About a minute             RouterB
f4351ef7dfda   chun/net:ifconfig   "/bin/bash"   About a minute ago   Up About a minute             RouterA

使用ovs划分网桥:sudo apt install openvswitch-switch

  • 创建一个网桥
    sudo ovs-vsctl add-br vswitch0
        Bridge vswitch0 
        Port vswitch0 
            Interface vswitch0 
                type: internal
    	ovs_version: "2.16.0"
    
  • 给三个容器添加网口
sudo ovs-docker add-port vswitch0 eth0 RouterA --ipaddress=192.168.100.1/24
sudo ovs-docker add-port vswitch0 eth0 RouterB --ipaddress=192.168.100.2/24
sudo ovs-docker add-port vswitch0 eth1 RouterB --ipaddress=192.168.200.1/24
sudo ovs-docker add-port vswitch0 eth0 RouterC --ipaddress=192.168.100.3/24
  • 现在宿主机上ifconfig会发现多了4个网卡信息
  • 在划分的网络里ping一下用于测试:
#  A->B
 ping 192.168.100.2 # 可以ping通
 ping 192.168.200.1 #不能ping通,不再同一个网段
 # A->C
 ping 192.168.100.3 # 可以ping通
 # B->C
 ping 192.168.100.3 # 可以ping通
  • 我们的容器是不能连接外网的,因为我们设置了 -net=none,三个容器之间相当于一个环形IO,离线的局域网
  • 设置vlan隔离,tag:
CONTAINER ID   IMAGE               COMMAND       CREATED        STATUS        PORTS     NAMES
2e78535122aa   chun/net:ifconfig   "/bin/bash"   16 hours ago   Up 16 hours             RouterC
a3a04a31c297   chun/net:ifconfig   "/bin/bash"   16 hours ago   Up 16 hours             RouterB
f4351ef7dfda   chun/net:ifconfig   "/bin/bash"   16 hours ago   Up 16 hours             RouterA
sudo ovs-docker set-vlan vswitch0 eth0 RouterA 100
sudo ovs-docker set-vlan vswitch0 eth0 RouterB 100
sudo ovs-docker set-vlan vswitch0 eth1 RouterB 200
sudo ovs-docker set-vlan vswitch0 eth0 RouterC 200

在这里插入图片描述

  • 测试一下:
#  A->B
 ping 192.168.100.2 # 可以ping通
 ping 192.168.200.1 #不能ping通,不再同一个网段
 # A->C
 ping 192.168.100.3 # 不能ping通,被隔离了
 # B->C
 ping 192.168.100.3 #  不能ping通,被隔离了
  • 怎么样实现vlan隔离的?

所谓的vlan隔离,实际上就是将每个网口加上一个vlan标识,我们称它为tag,正常来说拥有相同tag的同一网络下的设备是可以相通的,当然,我们不能这样来理解

  1. 每个网口希望接收到没有tag标识的信息;
  2. 如果交换机获取的带有tag的信息,它在转发给其它设备时,如果其它设备的tag信息与接收到的信息相同,交换机会转发并且丢弃tag信息

四、Docker网络配置__2021/12/16_ING

4.1.Bridge

In terms of networking, a bridge network is a Link Layer device which forwards traffic between network segments. A bridge can be a hardware device or a software device running within a host machine’s kernel…
https://docs.docker.com/network/bridge/

桥接会让Docker容器运行在宿主机的内核中,同一桥接网络下的容器可以通信,不同桥接 网络下的容器不能相互通信。在启动一个容器的时候,默认会使用桥接模式。当然,我们也可以使用User-defined brigde,自定义一个桥接网络。

用户定义的桥接网络和默认桥接的不同

User-defined bridges provide automatic DNS resolution between containers.

  • 用户定义的网络提供容器之间DNS的自动解析
    容器在默认桥接网络中只能通过ip地址互相通信,除非我们使用--link选项<见进阶操作 link>,这回使得多容器之间的通信相当复杂;在用户定义的桥接网络中,容器之间会解析容器名或者别名

User-defined bridges provide better isolation.

  • 用户定义的桥接网络提供更好的网络隔离
    假设我们的所有容器都没有指定--network,它们就都使用默认的桥接网络,这会导致所有的类型,无论是stacks/services/containers,它们都能相互通信(通过ip);而用户定义的桥接网络提供指定范围的容器之间才能通信

Containers can be attached and detached from user-defined networks on the fly.

五、使用Docker测试静态网站__2021/12/21_ING

5.1 Dockerfile构建简单的网站

创建一个sample web目录存放Dockerfile所需的一些东西:

sudo mkdir sample_web
cd sample_web
touch Dockerfile 
# 需要一些Nginx配置文件
sudo mkdir nginx && cd nginx
sudo wget https://raw.githubusercontent.com/jamtur01/dockerbook-code/master/code/5/sample/nginx/global.conf
sudo wget https://raw.githubusercontent.com/jamtur01/dockerbook-code/master/code/5/sample/nginx/nginx.conf
cd ..

下载不了咋办?

# nginx/global.conf
server {
        listen          0.0.0.0:80;
        server_name     _;

        root            /var/www/html/website;
        index           index.html index.htm;

        access_log      /var/log/nginx/default_access.log;
        error_log       /var/log/nginx/default_error.log;
}

# nginx/nginx.conf

user www-data;
worker_processes 4;
pid /run/nginx.pid;
daemon off;

events {  }

http {
  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;
  keepalive_timeout 65;
  types_hash_max_size 2048;
  include /etc/nginx/mime.types;
  default_type application/octet-stream;
  access_log /var/log/nginx/access.log;
  error_log /var/log/nginx/error.log;
  gzip on;
  gzip_disable "msie6";
  include /etc/nginx/conf.d/*.conf;
}

编写Dockerfile:

# 镜像的一些信息
# Version: 0.0.1
From ubuntu:21.10
MAINTAINER Chun '2857111062@qq.com'
ENV REFRESHED_AT 2021-12-21
# 安装nginx
RUN apt update
RUN apt -y -q install nginx
# 将配置文件加入镜像中
RUN mkdir -p /var/www/html/website
ADD nginx/global.conf /etc/nginx/conf.d/
ADD nginx/nginx.conf /etc/nginx/nginx.conf
# 公开80端口
EXPOSE 80

5.2 构建Sample网站和Nginx镜像

使用Dockerfile构建镜像:
sudo docker build -t sample/web .
如果提示update Error,则重启docker服务:service docker restart然后删除创建失败的镜像,防止build的时候使用其缓存

六、 使用mysql容器(腾讯云)

6.1 安装mysql镜像

拉取mysql8.0.25镜像

docker pull mysql:8.0.25

查看镜像:docker images

REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
mysql        8.0.25    5c62e459e087   8 months ago   556MB

启动镜像:

  • lower_case_table_name: 数据库忽略大小写
  • e 设置root账号密码
docker run -itd --name MYSQL -p3306:3306 -e MYSQL_ROOT_PASSWORD=root mysql:8.0.25 --lower_case_table_names=1

6.2 进入mysql容器设置

进入容器:docker exec -it MYSQL bash
连接mysql:

mysql -u root -p
> root

准备设置远程连接

use mysql;
# 主机不受限
grant all privileges on *.* to 'root'@'%';
# 让navicat可以连接,修改加密方式
alter user 'root'@'%' identified with mysql_native_password by 'root';
flush privileges;

6.3 宿主机设置

firewall-cmd --zone=public --add-port=3306/tcp --permanent
firewall-cmd --reload

在腾讯云服务器中添加防火墙规则:
在这里插入图片描述
然后就可以远程连接了

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐