前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Docker-进阶(容器网络、compose、harbor、swarm)

Docker-进阶(容器网络、compose、harbor、swarm)

作者头像
aruba
发布2022-09-28 12:59:41
6770
发布2022-09-28 12:59:41
举报
文章被收录于专栏:android技术android技术

接着Docker-入门,上次了解了Docker的基本命令,镜像容器操作,自定义镜像两种方式(容器和DockerFile),数据卷实现容器数据持久化和容器间数据共享,都是日常工作中最常用的。

一、Linux中的网卡与虚拟化

Docker本地容器之间的通信实现,就是利用的OS提供的网络虚拟化,所以了解OS的网卡和虚拟化有利于对Docker容器网络通信的了解

1.查看网卡信息

方式

描述

ip a

查看所有网卡信息

ip link show

查看网卡连接信息

ls /sys/class/net

网卡存放路径,显示所有网卡文件

执行命令:

代码语言:javascript
复制
-bash-4.2# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:8c:4f:3b brd ff:ff:ff:ff:ff:ff
    inet 192.168.42.4/24 brd 192.168.42.255 scope global noprefixroute dynamic ens33
       valid_lft 2610sec preferred_lft 2610sec
    inet6 2409:8920:5020:94ce:803d:cd84:9c91:3d7d/64 scope global noprefixroute dynamic 
       valid_lft 1167sec preferred_lft 1167sec
    inet6 2409:8921:5010:fe4:e1c5:8f4d:7a68:ecd5/64 scope global noprefixroute dynamic 
       valid_lft 3510sec preferred_lft 3510sec
    inet6 fe80::9de3:e8e0:6be0:4b41/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:1a:96:3a:45 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:1aff:fe96:3a45/64 scope link 
       valid_lft forever preferred_lft forever

网卡类型:

  • lo:本地网卡
  • ens33:连接网络的网卡
  • docker0:docker的网卡

网卡信息:

  • 状态:UP/DOWN/UNKOWN等
  • link/ether:MAC地址
  • inet:绑定的IP地址
2.网卡操作

命令

描述

ip addr add ip/掩码 dev 网卡名

为网卡添加IP

ip addr delete ip/掩码 dev 网卡名

删除网卡ip

ip link set 网卡名 up

启用网卡

ip link set 网卡名 down

停用网卡

ifup 网卡名

启用网卡

ifdown 网卡名

停用网卡

为网卡添加IP:

代码语言:javascript
复制
-bash-4.2# ip addr add 192.168.42.5/24 dev ens33
-bash-4.2# ip a |grep ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 192.168.42.4/24 brd 192.168.42.255 scope global noprefixroute dynamic ens33
    inet 192.168.42.5/24 scope global secondary ens33

删除网卡ip:

代码语言:javascript
复制
-bash-4.2# ip addr delete 192.168.42.5/24 dev ens33
-bash-4.2# ip a |grep ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 192.168.42.4/24 brd 192.168.42.255 scope global noprefixroute dynamic ens33
3.network namespace

network namespace能创建多个隔离的网络空间,每个空间拥有独立的网络信息。是实现网络虚拟化的重要功能

3.1 namespace操作

命令

描述

ip netns add 空间名

添加命名空间

ip netns list

查看所有命名空间

ip netns delete 空间名

删除命名空间

ip netns exec 空间名 网卡命令

执行命名空间中的网卡操作

添加命名空间,并查看该空间的网卡信息:

代码语言:javascript
复制
-bash-4.2# ip netns add ns1
-bash-4.2# ip netns list
ns1
-bash-4.2# ip netns exec ns1 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

可以看到,创建出的命名空间内,默认本地网卡是停用状态

3.2 veth pair

目前命名空间只有一个本地网卡,并不能和外界进行通讯,包括宿主机。 veth pair是一个成对的端口,是命名空间实现外界通讯的桥梁

命令

描述

ip link add 对1名 type veth peer name 对2名

创建veth pair

ip link set 网卡名 netns 空间名

为命名空间分配网卡

创建veth pair

代码语言:javascript
复制
-bash-4.2# ip link add veth-ns1 type veth peer name veth-ns2

-bash-4.2# ip a | grep veth
80: veth-ns2@veth-ns1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
81: veth-ns1@veth-ns2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000

-bash-4.2# ip addr add 192.168.42.1/24 dev veth-ns1

-bash-4.2# ip a | grep veth
80: veth-ns2@veth-ns1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
81: veth-ns1@veth-ns2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
    inet 192.168.42.1/24 scope global veth-ns1

veth-ns1分配给ns1空间,并分配IP与启用:

代码语言:javascript
复制
-bash-4.2# ip link set veth-ns1 netns ns1
-bash-4.2# ip netns exec ns1 ip addr add 192.168.42.1/24 dev veth-ns1
-bash-4.2# ip netns exec ns1 ip link set veth-ns1 up

-bash-4.2# ip netns exec ns1 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
81: veth-ns1@if80: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000
    link/ether 66:66:f8:22:c4:ae brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.42.1/24 scope global veth-ns1
       valid_lft forever preferred_lft forever
    inet6 fe80::6466:f8ff:fe22:c4ae/64 scope link 
       valid_lft forever preferred_lft forever

宿主机创建另一个命名空间ns2,并做相同的操作:

代码语言:javascript
复制
-bash-4.2# ip netns add ns2
-bash-4.2# ip netns list
ns2
ns1 (id: 0)

-bash-4.2# ip link set veth-ns2 netns ns2
-bash-4.2# ip netns exec ns2 ip addr add 192.168.42.2/24 dev veth-ns2
-bash-4.2# ip netns exec ns2 ip link set veth-ns2 up

-bash-4.2# ip netns exec ns2 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
80: veth-ns2@if81: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether c2:cd:24:23:ae:bc brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.42.2/24 scope global veth-ns2
       valid_lft forever preferred_lft forever
    inet6 fe80::c0cd:24ff:fe23:aebc/64 scope link 
       valid_lft forever preferred_lft forever

ping操作:

代码语言:javascript
复制
-bash-4.2# ip netns exec ns1 ping 192.168.42.2
PING 192.168.42.2 (192.168.42.2) 56(84) bytes of data.
64 bytes from 192.168.42.2: icmp_seq=1 ttl=64 time=0.618 ms
64 bytes from 192.168.42.2: icmp_seq=2 ttl=64 time=0.045 ms
^C
--- 192.168.42.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1005ms
rtt min/avg/max/mdev = 0.045/0.331/0.618/0.287 ms

二、Docker容器网络通信

1.准备工作

官方tomcat镜像不带扩展指令,需要自动搭建tomcat镜像

DockerFile内容,使用ADD将tomcat传入并解压,再安装JDK环境:

代码语言:javascript
复制
# 基础镜像
FROM centos-yum:1.0
MAINTAINER aruba

# 申明一个变量
ENV path /usr/local
# 设置工作目录
WORKDIR $path

# 安装tomcat java
ADD apache-tomcat-8.5.81.tar.gz $path
RUN yum install -y java-1.8.0-openjdk

EXPOSE 8080

# 最后执行命令
CMD /bin/bash | $path/apache-tomcat-8.5.81/bin/startup.sh

构建镜像:

代码语言:javascript
复制
docker build -f dockerfile3 -t centos-tomcat:latest .

最后创建两个容器:

代码语言:javascript
复制
-bash-4.2# docker run -i -d --name tm1 -p 8081:8080 tomcat   
-bash-4.2# docker run -i -d --name tm2 -p 8082:8080 tomcat
2.容器网络-Bridge
2.1 容器的网络

容器默认使用的是Bridge模式,查看两个容器的IP信息

代码语言:javascript
复制
-bash-4.2# docker exec -it tm1 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
140: eth0@if141: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

-bash-4.2# docker exec -it tm2 ip a 
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
142: eth0@if143: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

tm1对外网卡eth0@if141的IP为172.17.0.2,tm2对外网卡eth0@if143的IP为172.17.0.3,并且容器间可以ping通:

代码语言:javascript
复制
-bash-4.2# docker exec -it tm2 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=1.37 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.047 ms
^C
--- 172.17.0.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 0.047/0.710/1.373/0.663 ms
2.2 宿主机网络信息

查看宿主机IP信息:

代码语言:javascript
复制
-bash-4.2# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:8c:4f:3b brd ff:ff:ff:ff:ff:ff
    inet 192.168.42.4/24 brd 192.168.42.255 scope global noprefixroute dynamic ens33
       valid_lft 3446sec preferred_lft 3446sec
    inet6 2409:8921:5010:fe4:e1c5:8f4d:7a68:ecd5/64 scope global noprefixroute dynamic 
       valid_lft 3599sec preferred_lft 3599sec
    inet6 fe80::9de3:e8e0:6be0:4b41/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:1a:96:3a:45 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:1aff:fe96:3a45/64 scope link 
       valid_lft forever preferred_lft forever
141: veth346c0f4@if140: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 52:27:e5:72:82:1d brd ff:ff:ff:ff:ff:ff link-netnsid 2
    inet6 fe80::5027:e5ff:fe72:821d/64 scope link 
       valid_lft forever preferred_lft forever
143: veth3ed01fc@if142: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 72:38:9b:25:ca:98 brd ff:ff:ff:ff:ff:ff link-netnsid 3
    inet6 fe80::7038:9bff:fe25:ca98/64 scope link 
       valid_lft forever preferred_lft forever

发现除了之前的三个网卡外,还多了两个网卡:veth346c0f4@if140veth3ed01fc@if142,并且是由docker0创建的,注意docker0的IP为172.17.0.1,由此得知,每创建一个容器,docker会相对应的为该容器创建一个类似veth-pair的映射对,容器共享docker0的网络,在该网段下的容器都能够相互通信

3.docker网络操作

命令

描述

docker network ls

查看网络模式

docker network inspect 模式名

查看网络模式详情

docker network create [--subnet=ip网段/掩码 -d 模式] 模式名

创建新的网络模式

docker network rm 模式名

删除网络模式

docker network connect 模式名 容器名

赋予容器网络模式

docker run --network 模式名 容器名

创建时指定容器的网络模式

Docker默认只有三种:

代码语言:javascript
复制
-bash-4.2# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
965bd4c85719   bridge    bridge    local
38f75ca6b94e   host      host      local
1c340dce736e   none      null      local
3.1 创建新的网络模式
代码语言:javascript
复制
-bash-4.2# docker network create --subnet=172.18.0.0/24 tomcat-net
1b9a69c1df7359eda6652827e137661e6796f9524245b734200c69ed377d571d
3.2 指定容器网络模式

创建容器时指定网络:

代码语言:javascript
复制
-bash-4.2# docker run -i -d --name tm3 -p 8083:8080 --network tomcat-net centos-tomcat
b847abe2ab98501261a075e4a3282fd8fc804b7a727ba802cadee8c1e7e114c1

查看网络信息:

代码语言:javascript
复制
-bash-4.2# docker exec -it tm3 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
151: eth0@if152: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.18.0.2/24 brd 172.18.0.255 scope global eth0
       valid_lft forever preferred_lft forever
3.3 添加网络模式

由于tm3tm1处于不同的网段,所以ping不通:

代码语言:javascript
复制
-bash-4.2# docker exec -it tm3 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
^C
--- 172.17.0.2 ping statistics ---
10 packets transmitted, 0 received, 100% packet loss, time 9003ms

tm1添加网络,再次尝试ping:

代码语言:javascript
复制
-bash-4.2# docker network connect tomcat-net tm1

-bash-4.2# docker exec -it tm3 ping tm1
PING tm1 (172.18.0.3) 56(84) bytes of data.
64 bytes from tm1.tomcat-net (172.18.0.3): icmp_seq=1 ttl=64 time=0.117 ms
64 bytes from tm1.tomcat-net (172.18.0.3): icmp_seq=2 ttl=64 time=0.048 ms
64 bytes from tm1.tomcat-net (172.18.0.3): icmp_seq=3 ttl=64 time=0.048 ms
^C
--- tm1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2006ms
rtt min/avg/max/mdev = 0.048/0.071/0.117/0.032 ms
4.网络模式-Host

Host模式就是共享宿主机的网络,此时就不需要指定端口映射

代码语言:javascript
复制
-bash-4.2# docker run -d -i --name tm4 --network host centos-tomcat
3520c1b8d102bad92248d1193938aa8eabf62af456780f651c8857d7e2151992

浏览器上进行访问:

5.网络模式-None

None模式不能与外部进行通信,只有lo网卡:

代码语言:javascript
复制
-bash-4.2# docker run -i -d --name tm5 --network none centos-tomcat
18fe219a4f0e77f4a4cd8f756eec72cc90889f34b7def57326cceb09813c0e29

-bash-4.2# docker exec -it tm5 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever

三、DockerCompose

一台宿主机可能会部署多个容器,容器还可能有依赖关系,每次都手动启动容器是非常麻烦的,Compose就是定义和运行多容器的工具,使用yml文件配置应用程序需要的所有服务,使用docker-compose up命令创建并启动所有服务

官网地址:https://docs.docker.com/compose

1.compose安装

直接通过yum安装:

代码语言:javascript
复制
-bash-4.2# yum install -y docker-compose-plugin

-bash-4.2# docker compose version
Docker Compose version v2.6.0
2.官方demo入手

根据官网的demo来初次使用composehttps://docs.docker.com/compose/gettingstarted/

2.1 创建目录
代码语言:javascript
复制
 mkdir composetest
 cd composetest
2.2 创建app.py
代码语言:javascript
复制
vi app.py

内容为:

代码语言:javascript
复制
import time

import redis
from flask import Flask

app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)

def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)

@app.route('/')
def hello():
    count = get_hit_count()
    return 'Hello World! I have been seen {} times.\n'.format(count)
2.3 创建requirements.txt
代码语言:javascript
复制
vi requirements.txt

内容为:

代码语言:javascript
复制
flask
redis
2.4 创建Dockerfile
代码语言:javascript
复制
vi Dockerfile

内容为:

代码语言:javascript
复制
# syntax=docker/dockerfile:1
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]
2.5 创建docker-compose.yml
代码语言:javascript
复制
vi docker-compose.yml

内容为:

代码语言:javascript
复制
version: "3.9"
services:
  web:
    build: .
    ports:
      - "8000:5000"
  redis:
    image: "redis:alpine"
2.6 一键启动
代码语言:javascript
复制
docker compose up

等待镜像拉取等操作完成后,出现如下输出,说明启动成功:

另开终端查看docker镜像和容器信息:

浏览器访问:

3.配置规则

由上面的demo可以知道,compose的核心就是yml文件,在yml中可以配置各个容器,以及容器的依赖关系,yml的可配置项有很多,官方文档查看:https://docs.docker.com/compose/compose-file/compose-file-v3/

常用的如下:

代码语言:javascript
复制
version: "3.9" #配置文件版本

services:  #各个服务
  容器名1:
    build: . #dockerfile路径
    image: centos #容器使用的镜像
    expose: 8080 #对外开放端口
    restart: always #自动重启
  容器名2:
    depends_on: # 依赖启动
      - 容器名1
    ports: #端口映射关系
      - "8000:5000"
    volumes: #数据卷
      # - 宿主机绝对路径/卷标:容器目标路径
      - db_data:/var/lib/mysql  # 卷标方式
      - /root/mysql:/var/lib/mysql2 # 绝对路径方式
    environment: #环境配置

volumes: # 卷标配置
  # 卷标名:[路径地址/{}自动生成目录]
  db_data: {}
4.常用命令

docker compose命令都需要在工作目录下进行,如上述的composetest目录下

命令

描述

docker compose up

根据yml创建service 使用-f指定yml文件,-d守护模式

docker compose ps

查看启动的服务

docker compose images

查看镜像

docker compose stop/start

停止和启动服务

docker compose down

停止并删除服务,数据卷和network

docker compose exec 服务名 命令

执行某个服务的命令

5.部署WP博客

创建目录:

代码语言:javascript
复制
mkdir my_wordpress
cd my_wordpress

docker-compose.yml文件:

代码语言:javascript
复制
version: "3.9"

services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    volumes:
      - wordpress_data:/var/www/html
    ports:
      - "8000:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress

volumes:
  db_data: {}
  wordpress_data: {}

一键启动:

代码语言:javascript
复制
docker compose up

浏览器访问:

6.水平扩展

水平扩展也很简单,一条命令即可:

代码语言:javascript
复制
docker compose up --scale 服务名=扩展数量 -d

运用:

代码语言:javascript
复制
-bash-4.2# docker compose ps
NAME                       COMMAND                  SERVICE             STATUS              PORTS
my_wordpress-db-1          "docker-entrypoint.s…"   db                  running             33060/tcp
my_wordpress-wordpress-1   "docker-entrypoint.s…"   wordpress           running             0.0.0.0:8000->80/tcp, :::8000->80/tcp

-bash-4.2# docker compose up --scale db=4 -d
[+] Running 5/5
 ⠿ Container my_wordpress-db-4         St...                               4.3s
 ⠿ Container my_wordpress-db-1         St...                               4.7s
 ⠿ Container my_wordpress-db-2         St...                               5.2s
 ⠿ Container my_wordpress-db-3         St...                               5.1s
 ⠿ Container my_wordpress-wordpress-1  Started                             4.3s

四、Harbor

Harbor是私有的镜像仓库,实际开发项目中,必然有自己打包的镜像,需要上传到仓库,以便于其他开发和运维人员拉取,首先来看下如何上传到Docker Hub

1.Docker Hub镜像上传
1.1 登录Docker Hub

如果没有账号,需要去注册:https://hub.docker.com/

代码语言:javascript
复制
docker login

输入账号密码后提示登陆成功:

代码语言:javascript
复制
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
1.2 docker tag修改镜像名

上传到docker hub有一个规则,即镜像名需要包含账号id(账户名),具体规则为:userId/镜像名

可以通过命令修改:docker tag 新镜像名 原镜像名

修改镜像名后,上传:

代码语言:javascript
复制
-bash-4.2# docker images
REPOSITORY        TAG       IMAGE ID       CREATED         SIZE
composetest_web   latest    0f00ff5df20b   2 hours ago     185MB
centos-tomcat     latest    8175d2379676   5 hours ago     643MB
centos-share      1.0       281ec8de6b48   9 hours ago     458MB
centos-vim        1.0       eb36a8966f6b   10 hours ago    458MB
centos-yum        1.0       ab2bd0073604   10 hours ago    366MB
tomcat-hello      1.0       ba5599c90061   14 hours ago    680MB
tomcat            latest    fb5657adc892   8 months ago    680MB
wordpress         latest    c3c92cc3dcb1   8 months ago    616MB
mysql             5.7       c20987f18b13   8 months ago    448MB
redis             alpine    3900abf41552   9 months ago    32.4MB
centos            latest    5d0da3dc9764   11 months ago   231MB


-bash-4.2# docker tag centos-tomcat aruba233/centos-tomcat

-bash-4.2# docker push aruba233/centos-tomcat             
Using default tag: latest
The push refers to repository [docker.io/aruba233/centos-tomcat]
1b2f91c23757: Pushed 
3cf600e944ba: Pushed 
3cc84259d05d: Pushed 
74ddd0ec08fa: Mounted from library/centos 
latest: digest: sha256:c04d539be1ae8e21d9293ff7adeb74de9acbde9b96a509e3ce9037415edae408 size: 1167

上传成功后,就可以在docker hub上搜索到了:

2. 镜像上传

如果嫌docker hub网络太慢,可以使用仓库:

2.1 创建实例
2.2 创建命名空间
2.3 创建仓库

创建完成后会有提示如何使用:

2.4 上传镜像

根据提示操作即可

登录:

代码语言:javascript
复制
docker login --username=aliyun0098478676 registry.cn-hangzhou.aliyuncs.com

重命名镜像:

代码语言:javascript
复制
docker tag 8175 registry.cn-hangzhou.aliyuncs.com/aruba/centos-tomcat:latest

上传镜像:

代码语言:javascript
复制
docker push registry.cn-hangzhou.aliyuncs.com/aruba/centos-tomcat:latest
3. Harbor

上面两种都是公共仓库,想在自己服务器上搭建一个仓库也是必不可少的,Harbor就是由由VMware开源的Docker镜像仓库管理项目

3.1 Harbor安装

官网:https://goharbor.io/

下载地址:https://github.com/goharbor/harbor/releases

下载后,传入linux系统,进行解压:

代码语言:javascript
复制
tar -xvf harbor-offline-installer-v2.6.0.tgz 
mv harbor /usr/local

修改配置文件:

代码语言:javascript
复制
cd /usr/local/harbor
cp harbor.yml.tmpl harbor.yml
vi harbor.yml

修改如下3处,换成自己对应的IP:

3.2 配置证书

harbor内部使用nginx反向代理和https,所以要配置CA签名证书

3.2.1 生成CA证书

代码语言:javascript
复制
-bash-4.2# openssl genrsa -out ca.key 4096

-bash-4.2# openssl req -x509 -new -nodes -sha512 -days 3650 \
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=192.168.42.4" \
-key ca.key -out ca.crt

3.2.2 生成服务器公私钥

代码语言:javascript
复制
-bash-4.2# openssl genrsa -out 192.168.42.4.key

-bash-4.2# openssl req -sha512 -new \
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=192.168.42.4" \
-key 192.168.42.4.key -out 192.168.42.4.csr

3.2.3 生成一个x509 v3扩展文件

  • 域名方式:
代码语言:javascript
复制
-bash-4.2# cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1=harbor.od.com
DNS.2=harbor.od.com
DNS.3=harbor.od.com
EOF
  • IP方式:
代码语言:javascript
复制
-bash-4.2# cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = IP:192.168.42.4
EOF

3.2.4 生成CA签名证书

代码语言:javascript
复制
-bash-4.2# openssl x509 -req -sha512 -days 3650 \
-extfile v3.ext \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-in 192.168.42.4.csr \
-out 192.168.42.4.crt

3.2.5 将CA签名证书和服务器私钥放入/data/cert/目录

代码语言:javascript
复制
-bash-4.2# mkdir -p /data/cert/
-bash-4.2# cp 192.168.42.4.crt /data/cert/
-bash-4.2# cp 192.168.42.4.key /data/cert/
3.3 Docker配置证书

上面我们为harbor准备了证书,同样Docker也需要进行配置,因为Docker是要与仓库进行交互的

3.3.1 CA签名证书类型crt转换为cert

代码语言:javascript
复制
-bash-4.2# openssl x509 -inform PEM -in 192.168.42.4.crt -out 192.168.42.4.cert 

3.3.2 存放到Docker的证书目录

docker需要CA公钥,CA签名证书(cert文件)与服务器私钥:

代码语言:javascript
复制
-bash-4.2# mkdir -p /etc/docker/certs.d/192.168.42.4/
-bash-4.2# cp 192.168.42.4.key /etc/docker/certs.d/192.168.42.4/ 
-bash-4.2# cp 192.168.42.4.cert /etc/docker/certs.d/192.168.42.4/
-bash-4.2# cp ca.crt /etc/docker/certs.d/192.168.42.4/

3.3.3 重启Docker

代码语言:javascript
复制
systemctl restart docker
3.4 初始化harbor

执行harbor的prepare脚本,为nginx配置HTTPS,此过程会拉取nginx镜像:

代码语言:javascript
复制
-bash-4.2# ./prepare

执行harbor的install脚本,初始化harbor:

代码语言:javascript
复制
-bash-4.2# ./install.sh

运行harbor

代码语言:javascript
复制
-bash-4.2# docker compose up

浏览器中访问:

yml中可以找到默认的登录账号密码:admin/Harbor12345

正常登录后:

3.5 部署harbor项目

harbor上创建一个项目:

再创建一个账号:

为该账号赋予管理员权限:

将该账户分配为刚刚创建项目的成员:

3.6 上传镜像到harbor

Docker登录到harbor:

代码语言:javascript
复制
-bash-4.2# docker login 192.168.42.4

上传镜像:

代码语言:javascript
复制
-bash-4.2# docker tag centos-tomcat 192.168.42.4/aruba/centos-tomcat:latest

-bash-4.2# docker push 192.168.42.4/aruba/centos-tomcat:latest

等待上传成功后,查看harbor中的镜像仓库:

五、Swarm

前面我们了解了Docker容器间通信,使用虚拟网络技术实现,但还有一个问题,对于多台服务器部署的docker容器间通信,该如何实现呢? Swarm是Docker官方提供的一款集群管理工具,由若干个Docker管理机抽象成一个整体,一个Docker管理机又能集中管理它下面的Docker工作机,功能与k8s类似,但更轻量,功能也比k8s少些

Swarm和Redis集群一样遵循半数原则,超过1/2(包括1/2)个Manager节点挂了,整个集群将不可用

1.集群搭建
1.1 克隆虚拟机

克隆三台虚拟机,分别设置HOSTNAME,以便后续标识

修改/etc/sysconfig/network

代码语言:javascript
复制
-bash-4.2# vi /etc/sysconfig/network

内容为:

代码语言:javascript
复制
# Created by anaconda
NETWORKING=yes
HOSTNAME=manager

修改/etc/hosts

代码语言:javascript
复制
-bash-4.2# vi /etc/hosts

追加内容:

代码语言:javascript
复制
192.168.42.4 manager

另外两台也做相应的配置,只是主机名不同,修改完后重启

1.2 集群搭建

Manager节点执行下面命令:

代码语言:javascript
复制
-bash-4.2# docker swarm init --advertise-addr 192.168.42.4
Swarm initialized: current node (7ltgt5p0vggy3w876p0k5xfrn) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-1w3lb9uhu3hnsipp1iz7ogmvsatcon2zeufxysagd3sbf663fh-dqqdm5d5l7a96fe4g7qh96ffl 192.168.42.4:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

其他节点执行上面的提示命令,加入到集群中:

代码语言:javascript
复制
-bash-4.2# docker swarm join --token SWMTKN-1-1w3lb9uhu3hnsipp1iz7ogmvsatcon2zeufxysagd3sbf663fh-dqqdm5d5l7a96fe4g7qh96ffl 192.168.42.4:2377
This node joined a swarm as a worker.
1.3 docker node ls查看集群节点

查看集群节点,可以看到一个manager statusLeader,即Manager节点:

代码语言:javascript
复制
-bash-4.2# docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
7ltgt5p0vggy3w876p0k5xfrn *   manager    Ready     Active         Leader           20.10.17
rtavw2dgchlmhjmfth2uv0pnc     node1      Ready     Active                          20.10.17
979ie68u7wn73w3nvlc315ldp     node2      Ready     Active                          20.10.17
1.4 节点类型转换

Manager节点可以将Worker节点的类型进行升降级

命令

描述

docker node promote 主机名

将节点升级为Manager节点

docker node demote 主机名

将节点降级为Worker节点

将一个节点升级为Manager节点:

代码语言:javascript
复制
-bash-4.2# docker node promote node1
Node node1 promoted to a manager in the swarm.

-bash-4.2# docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
7ltgt5p0vggy3w876p0k5xfrn *   manager    Ready     Active         Leader           20.10.17
rtavw2dgchlmhjmfth2uv0pnc     node1      Ready     Active         Reachable        20.10.17
979ie68u7wn73w3nvlc315ldp     node2      Ready     Active                          20.10.17
2.集群半数协议(Raft一致性协议)

由于我们只有三个节点,所以要测试集群可用,只能把三个节点都上升为Manager节点,都上升完后,关闭Leader主机后,查看节点状态,发现有一台Worker已经成为Leader节点了:

代码语言:javascript
复制
-bash-4.2# docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
7ltgt5p0vggy3w876p0k5xfrn     manager    Unknown   Active         Unreachable      20.10.17
rtavw2dgchlmhjmfth2uv0pnc *   node1      Ready     Active         Leader           20.10.17
979ie68u7wn73w3nvlc315ldp     node2      Ready     Active         Reachable        20.10.17
3.Swarm服务编排

上面compose可以在一个宿主机上实现水平扩展,Swarm则可以在Docker集群中实现水平扩展,容器是Docker中的叫法,在Swarm中,称为服务Service

Service相关命令如下:

命令

描述

docker service create --name 名称 -p 端口映射 镜像名

创建一个service

docker service ls

列举出所有swarm服务

docker service logs 服务名

查看对应服务的日志输出

docker service inspect 服务名

查看服务详情

docker service ps 服务名

列举出对应服务的容器信息,信息包含运行的主机

docker service scale 服务名=扩展数量

水平扩展服务,将自动扩展到docker集群的节点中

docker service rm 服务名

删除服务

3.1 创建Service
代码语言:javascript
复制
-bash-4.2# docker service create  --name tomcat-service tomcat

成功后查看服务:

代码语言:javascript
复制
-bash-4.2# docker service ls
ID             NAME             MODE         REPLICAS   IMAGE           PORTS
ay4xeyz5qd1a   tomcat-service   replicated   1/1        tomcat:latest 

再查看容器信息,发现创建在node2上:

代码语言:javascript
复制
-bash-4.2# docker service ps tomcat-service
ID             NAME               IMAGE           NODE      DESIRED STATE   CURRENT STATE           ERROR     PORTS
g90gcs36uzlv   tomcat-service.1   tomcat:latest   node2     Running         Running 8 minutes ago 
3.2 水平扩展

将service扩展到3个:

代码语言:javascript
复制
-bash-4.2# docker service scale tomcat-service=3
tomcat-service scaled to 3
overall progress: 3 out of 3 tasks 
1/3: running   
2/3: running   
3/3: running   
verify: Service converged 

再次查看容器信息,发现三个节点上都创建了:

代码语言:javascript
复制
-bash-4.2# docker service ps tomcat-service     
ID             NAME               IMAGE           NODE      DESIRED STATE   CURRENT STATE                    ERROR     PORTS
g90gcs36uzlv   tomcat-service.1   tomcat:latest   node2     Running         Running 11 minutes ago                     
gh45bx3jwn57   tomcat-service.2   tomcat:latest   manager   Running         Running about a minute ago                 
xfmeqdob533o   tomcat-service.3   tomcat:latest   node1     Running         Running less than a second ago   
3.3 自动创建与重启

如果手动停止或删除容器,或者遇到异常导致服务崩溃退出,Swarm还是会自动创建启动容器,以拉起服务

随便找个节点将tomcat-service容器停止,发现又会有一个新的容器被创建并启动:

代码语言:javascript
复制
-bash-4.2# docker ps | grep tomcat-service
58ac6e5387bf   tomcat:latest                   "catalina.sh run"        3 minutes ago   Up 3 minutes                       8080/tcp                                                                         tomcat-service.3.abmm4wcn8l7kabndc7jz3xset

-bash-4.2# docker stop 58ac6e5387bf
58ac6e5387bf

-bash-4.2# docker ps | grep tomcat-service
4a4902622d93   tomcat:latest                   "catalina.sh run"        6 seconds ago   Up Less than a second              8080/tcp                                                                         tomcat-service.3.mxt6k34ad4jltrnstf7qarbja
4.多机通信

Swarm是通过VXLAN(Virtual eXtensible LAN)实现的多机之间的通信,VXLAN(Virtual eXtensible LAN)技术是当前最为主流的Overlay标准,仅仅做了解即可

重新部署一个tomcat服务:

代码语言:javascript
复制
-bash-4.2# docker service create -d  --name mytomcat -p 8080:8080 tomcat 
ph2b51mqz9tbcogsiiu7e71ny

-bash-4.2# docker service ps mytomcat
ID             NAME         IMAGE           NODE      DESIRED STATE   CURRENT STATE           ERROR     PORTS
8yzqrwmtj41j   mytomcat.1   tomcat:latest   manager   Running         Running 6 seconds ago 

从上面可知,目前服务只部署在一个节点上,Manager节点的IP为:192.168.42.4,使用其他节点IP在浏览器进行访问:

结果发现其他节点同样可以访问,这就是VXLAN实现的,可以通过网络命令查看下:

代码语言:javascript
复制
-bash-4.2# docker network ls
NETWORK ID     NAME              DRIVER    SCOPE
48ea34f8d77f   bridge            bridge    local
2d68d63c8396   docker_gwbridge   bridge    local
9a32710598fb   harbor_harbor     bridge    local
38f75ca6b94e   host              host      local
f4cb49asob14   ingress           overlay   swarm
1c340dce736e   none              null      local

发现ingress的类型为overlay

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-09-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、Linux中的网卡与虚拟化
    • 1.查看网卡信息
      • 2.网卡操作
        • 3.network namespace
          • 3.1 namespace操作
          • 3.2 veth pair
      • 二、Docker容器网络通信
        • 1.准备工作
          • 2.容器网络-Bridge
            • 2.1 容器的网络
            • 2.2 宿主机网络信息
          • 3.docker网络操作
            • 3.1 创建新的网络模式
            • 3.2 指定容器网络模式
            • 3.3 添加网络模式
          • 4.网络模式-Host
            • 5.网络模式-None
            • 三、DockerCompose
              • 1.compose安装
                • 2.官方demo入手
                  • 2.1 创建目录
                  • 2.2 创建app.py
                  • 2.3 创建requirements.txt
                  • 2.4 创建Dockerfile
                  • 2.5 创建docker-compose.yml
                  • 2.6 一键启动
                • 3.配置规则
                  • 4.常用命令
                    • 5.部署WP博客
                      • 6.水平扩展
                      • 四、Harbor
                        • 1.Docker Hub镜像上传
                          • 1.1 登录Docker Hub
                          • 1.2 docker tag修改镜像名
                        • 2. 镜像上传
                          • 2.1 创建实例
                          • 2.2 创建命名空间
                          • 2.3 创建仓库
                          • 2.4 上传镜像
                        • 3. Harbor
                          • 3.1 Harbor安装
                          • 3.2 配置证书
                          • 3.3 Docker配置证书
                          • 3.4 初始化harbor
                          • 3.5 部署harbor项目
                          • 3.6 上传镜像到harbor
                      • 五、Swarm
                        • 1.集群搭建
                          • 1.1 克隆虚拟机
                          • 1.2 集群搭建
                          • 1.3 docker node ls查看集群节点
                          • 1.4 节点类型转换
                        • 2.集群半数协议(Raft一致性协议)
                          • 3.Swarm服务编排
                            • 3.1 创建Service
                            • 3.2 水平扩展
                            • 3.3 自动创建与重启
                          • 4.多机通信
                          相关产品与服务
                          容器服务
                          腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档