Skip to main content
开放网络的先行者与推动者—星融元
加入我们技术支持(Support)  TEL:(+86)4000989811

配置指导:OpenStack-Helm部署-AIO模式

1 目标

本文档以Ubuntu 18为基础操作环境,简要介绍OpenStack-Helm项目的基本概念,以及以All in one模式部署的具体方法。

2 概要介绍

OpenStack项目各组件本已纷繁复杂,再使用Kubernetes去部署承载OpenStack的各组件就更加复杂了。而Helm最大的优势就是对Kubernetes复杂应用的管理,Helm就相当于Linux的包管理工具YUM,只是它管理的“程序包”是一些互相耦合、打包后的YAML配置文件与资源文件。使用一个更容理解的类比,即在Kubernetes中使用Helm来部署管理Chart,就相当于在安卓手机中使用应用商店来安装管理APP。

Helm相关组件、概念以及原理:

Helm包含两个重要组件,分别是Helm客户端和Tiller服务器。

  • Helm是一个命令行工具,用于本地开发及管理Chart、Chart仓库等;
  • Tiller是Helm的服务端。Tiller负责接收Helm的请求,与K8S的 APIServer进行交互,根据Chart来生成 Release并管理Release的整个生命周期;
  • ChartHelm的打包格式叫做Chart,所谓Chart就是一系列配置文件, 它描述了一组相关的K8S集群资源;
  • Release使用helm install命令在Kubernetes集群中部署的Chart称为Release;
  • RepoistoryHelm Chart的仓库,Helm客户端通过HTTP协议来访问仓库中Chart的索引文件和压缩包。

下图描述了Helm的几个关键组件Helm、Tiller、Repository、Chart之间的关系以及它们之间的工作流程。

Helm的关键组件

OpenStack-Helm这个项目最主要的工作就是进行OpenStack各组件的Chart开发,将各个组件封装为不同的Chart,在运维OpenStack的过程中,不再管理具体的程序进程、容器或者是K8S的Pod,而是直接管理更粗粒度的Release,以尽可能降低OpenStack在K8S上的部署、运维的复杂度。

3 环境准备

3.1 系统版本

  • 操作系统:Ubuntu 18.04.5 LTS (bionic);

3.2 节点配置与部署模式

主机名IP地址处理器内存硬盘节点角色
noone-virtual-machine192.168.2.233 管理口16C32G200G 系统盘All in one
表3.1:各节点配置与角色

为了OpenStack-Helm项目的快速部署、验证与研究,本次部署采用AIO(All in one)模式,因此需要注意的是,若要安装所有的功能模块至少保证服务器的内存资源不小于16G,否则可能会导致部署失败。

3.3 实施部署前的环境准备

进行实施部署前的环境准备工作,包括系统基础环境和网络代理配置。

  • 配置Sudo免密:
noone@noone-virtual-machine:~$ chmod +w /etc/sudoers
noone@noone-virtual-machine:~$ sudo vim /etc/sudoers
noone@noone-virtual-machine:~$ sudo cat /etc/sudoers
#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults	env_reset
Defaults	mail_badpass
Defaults	secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"

# Host alias specification

# User alias specification

# Cmnd alias specification

# User privilege specification
root	ALL=(ALL:ALL) ALL

# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

# Allow members of group sudo to execute any command
%sudo	ALL=(ALL:ALL) ALL

# See sudoers(5) for more information on "#include" directives:
noone	ALL=(ALL) NOPASSWD:ALL

#includedir /etc/sudoers.d
noone@noone-virtual-machine:~$
  • 配置Ubuntu的软件源列表、更新系统中的软件包:
noone@noone-virtual-machine:~$ cd /etc/apt/
noone@noone-virtual-machine:/etc/apt$ cat sources.list
deb http://mirrors.163.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-backports main restricted universe multiverse
noone@noone-virtual-machine:/etc/apt$ sudo apt update
noone@noone-virtual-machine:/etc/apt$ sudo apt upgrade
  • 安装Git工具,拉取项目文件:
noone@noone-virtual-machine:~$ mkdir openstack
noone@noone-virtual-machine:~/openstack$ sudo apt-get install git
noone@noone-virtual-machine:~/openstack$ vim git-clone-helm.sh
noone@noone-virtual-machine:~/openstack$ cat git-clone-helm.sh
#!/bin/bash
set -xe

git clone https://opendev.org/openstack/openstack-helm-infra.git
git clone https://opendev.org/openstack/openstack-helm.git
noone@noone-virtual-machine:~/openstack$ bash git-clone-helm.sh
  • 安装配置代理工具,用于代理终端命令行工具产生的流量(Docker镜像拉取):

安装代理软件:

noone@noone-virtual-machine:~$ sudo apt install privoxy

编辑代理软件的配置文件:

noone@noone-virtual-machine:~$ sudo vim /etc/privoxy/config
......
#      Suppose you are running Privoxy on an IPv6-capable machine and
#      you want it to listen on the IPv6 address of the loopback
#      device:
#
#        listen-address [::1]:8118
#
listen-address  127.0.0.1:8118
listen-address  [::1]:8118
#
......
#      To chain Privoxy and Tor, both running on the same system, you
#      would use something like:
#
#        forward-socks5t   /               127.0.0.1:9050 .
#
注释:
此处的配置,将本地转发到8118端口的流量,转发到192.168.0.60:10808,此接口是局域网中代理软件提供的
forward-socks5 / 192.168.0.60:10808 .
#
#      Note that if you got Tor through one of the bundles, you may
#      have to change the port from 9050 to 9150 (or even another
#      one). For details, please check the documentation on the Tor
#      website.
#
#      The public Tor network can't be used to reach your local
#      network, if you need to access local servers you therefore
#      might want to make some exceptions:
#
#        forward         192.168.*.*/     .
#        forward            10.*.*.*/     .
#        forward           127.*.*.*/     .
#
forward         192.168.*.*/     .
forward            10.*.*.*/     .
forward           127.*.*.*/     .
forward           172.24.*.*/    .
#
......
#  Examples:
#
#      forwarded-connect-retries 1
#
forwarded-connect-retries  1
#
......

重启代理软件并设置为开机自启:

noone@noone-virtual-machine:~$ sudo systemctl enable privoxy
noone@noone-virtual-machine:~$ sudo systemctl restart privoxy

在.bashrc文件末尾追加环境变量配置,使得命令行工具产生的流量转发给Privoxy软件进行处理:

noone@noone-virtual-machine:~$ vim ~/.bashrc 
export ftp_proxy="127.0.0.1:8118"
export http_proxy="127.0.0.1:8118"
export https_proxy="127.0.0.1:8118"
export no_proxy="localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,172.24.0.0/12,192.168.0.0/16,172.17.0.1,
.svc.cluster.local"

命令行工具流量代理的效果测试:

noone@noone-virtual-machine:/tmp$ wget www.google.com
--2021-03-24 10:21:45--  http://www.google.com/
Connecting to 127.0.0.1:8118... connected.
Proxy request sent, awaiting response... 200 OK
Length: 12823 (13K) [text/html]
Saving to: ‘index.html’

index.html                                                  100%[=====>]  12.52K  --.-KB/s    in 0s      

2021-03-24 10:21:47 (187 MB/s) - ‘index.html’ saved [12823/12823]

noone@noone-virtual-machine:/tmp$
  • 修改NSSwitch配置文件指定行:
noone@noone-virtual-machine:~$ cat /etc/nsswitch.conf 
# /etc/nsswitch.conf
#
# Example configuration of GNU Name Service Switch functionality.
# If you have the `glibc-doc-reference' and `info' packages installed, try:
# `info libc "Name Service Switch"' for information about this file.
……

hosts:          files dns

……
noone@noone-virtual-machine:~$

4 安装步骤

此次为AIO模式部署,因此所有的OpenStack组件的容器都部署在同一节点,由于网络环境影响,即使配置了代理也会经常有网络抖动、中断,因此在执行脚本过程中若因网络导致失败,可以多重复执行几次。工作目录如下:

noone@noone-virtual-machine:~$ cd openstack/openstack-helm
noone@noone-virtual-machine:~/openstack/openstack-helm$ pwd
/home/noone/openstack/openstack-helm

4.1 部署Kubernetes、Helm

./tools/deployment/developer/common/010-deploy-k8s.sh
./tools/deployment/developer/common/020-setup-client.sh

4.2 部署Ingress Controller

./tools/deployment/component/common/ingress.sh

4.3 部署NFS Provisioner

./tools/deployment/developer/nfs/040-nfs-provisioner.sh

4.4 部署MariaDB

./tools/deployment/developer/nfs/050-mariadb.sh

4.5 部署RabbitMQ

./tools/deployment/developer/nfs/060-rabbitmq.sh

4.6 部署Memcached

./tools/deployment/developer/nfs/070-memcached.sh

4.7 部署Keystone

编辑此脚本文件,注释掉replace_variables函数的所有调用:

/home/noone/openstack/openstack-helm/tools/deployment/common/get-values-overrides.sh

然后,再执行相关脚本:

./tools/deployment/developer/nfs/080-keystone.sh

4.8 部署Heat

./tools/deployment/developer/nfs/090-heat.sh

4.9 部署Horizon

./tools/deployment/developer/nfs/100-horizon.sh

4.10 部署Glance

./tools/deployment/developer/nfs/120-glance.sh

4.11 部署OpenvSwitch

./tools/deployment/developer/nfs/140-openvswitch.sh

4.12 部署Libvirt

./tools/deployment/developer/nfs/150-libvirt.sh

4.13 部署Compute Kit (Nova and Neutron)

./tools/deployment/developer/nfs/160-compute-kit.sh

4.14 配置外部网络访问网关

./tools/deployment/developer/nfs/170-setup-gateway.sh

4.15 部署结果验证

确保各个OpenStack组件的Pod都达到预期状态,如果有部分容器启动失败,可以借助Kuboard进一步调试。

noone@noone-virtual-machine:~/openstack/openstack-helm$ kubectl -n openstack get deployment
NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
glance-api                    1/1     1            1           8d
glance-registry                1/1     1            1           8d
heat-api                      1/1     1            1           9d
heat-cfn                      1/1     1            1           9d
heat-engine                   1/1     1            1           9d
horizon                       1/1     1            1           9d
ingress                       1/1     1            1           9d
ingress-error-pages            1/1     1            1           9d
keystone-api                  1/1     1            1           9d
mariadb-ingress               2/2     2            2           9d
mariadb-ingress-error-pages    1/1     1            1           9d
memcached-memcached       1/1     1            1           9d
neutron-server                 1/1     1            1           8d
nova-api-metadata             1/1     1            1           8d
nova-api-osapi                 1/1     1            1           8d	
nova-conductor                1/1     1            1           8d
nova-consoleauth              1/1     1            1           8d
nova-novncproxy               1/1     1            1           8d
nova-scheduler                1/1     1            1           8d
placement-api                 1/1     1            1           8d
noone@noone-virtual-machine:~/openstack/openstack-helm$

在确认各个容器启动成功后,使用Ingress提供的URL访问OpenStack Horizon。

noone@noone-virtual-machine:~/openstack/openstack-helm$ kubectl -n openstack get ingress
……
horizon        <none>        horizon,horizon.openstack,horizon.openstack.svc.cluster.local
……
OpenStack Horizon的Web界面

为进一步确保OpenStack基础功能运行正常,创建两台虚拟机,进行通讯测试。

创建两台虚拟机进行通讯测试
测试结果

成功创建了两台虚拟机,虚拟机可以正常启动,并在使用VxLAN网络创建的VPC下成功互通,结果符合预期。

5 Kubernetes可视化管理面板安装

在整个部署过程中,会产生各种意料之外的容器错误,为了方便排错,安装可视化管理面板进行日志分析错误定位。

noone@noone-virtual-machine:~/openstack$ vim deploy-kuboard.sh
noone@noone-virtual-machine:~/openstack$ cat deploy-kuboard.sh
#!/bin/bash

sudo docker run -d \
  --restart=unless-stopped \
  --name=kuboard \
  -p 10080:80/tcp \
  -p 10081:10081/udp \
  -p 10081:10081/tcp \
  -e KUBOARD_ENDPOINT="http://192.168.2.233:10080" \
  -e KUBOARD_AGENT_SERVER_UDP_PORT="10081" \
  -e KUBOARD_AGENT_SERVER_TCP_PORT="10081" \
  -v /root/kuboard-data:/data \
  eipwork/kuboard:v3
# 国内可以使用镜像 swr.cn-east-2.myhuaweicloud.com/kuboard/kuboard:v3 ,以更快地完成下载
# 请不要使用 127.0.0.1 或者 localhost 作为内网 IP,默认用户名密码:admin/Kuboard123
noone@noone-virtual-machine:~/openstack$ bash deploy-kuboard.sh

待所有Kuboard容器正常启动后,使用默认用户名密码进行登录,界面如下图所示,集群导入管理等操作不再赘述。

Kubernetes多集群管理登录界面
集群导入管理

6 参考资料

【1】 OpenStack-Helm Document

【2】 External DNS to FQDN/Ingress

【3】 Privoxy在Ubuntu-18中的安装与配置

【4】 Fix(script): removes replacement overrides

更多内容请参考:A-Lab

配置指导:Harbor容器镜像仓库高可用方案

1 Harbor简介

Docker容器应用的开发和运行离不开可靠的镜像管理,Docker官方提供了原生的Registry,但其功能比较简单,而且没有可视化界面,自然无法满足企业级的需求。虽然Docker官方也提供了公共的镜像仓库,但是从安全和效率等方面考虑,部署私有环境内的Registry也是非常必要的。

为了解决以上需求,VMware公司推出了Harbor,Harbor 是为企业用户设计的容器镜像仓库开源项目,包括了权限管理(RBAC)、LDAP、安全漏洞扫描、镜像验真、管理界面、自我注册、HA 等企业必需的功能。

2 Harbor架构图

Harbor架构图

3 Harbor必要组件

  • Proxy:用于转发用户的请求到后端的反向代理,通过Nginx官方镜像实现
  • Registry:原生的Docker镜像仓库,负责存储镜像文件,实现Pull/Push等功能
  • Database:保存项目/用户/角色/复制策略等信息到数据中,这里使用的镜像是Postgres数据库,而不是传统的Mariadb/Mysql
  • Core Service:提供图形化操作界面,帮助用户管理Registry上的镜像,并对用户进行授权
  • Job Services:镜像复制,用户可以配置在Harbor实例之间进行镜像的复制和同步等操作
  • Log Collector:日志收集,负责收集各个镜像的日志进行统一管理

4 Harbor虚机配置

主机系统IP地址节点角色
Harbor-1Centos7.6192.168.4.200Master
Harbor-2Centos7.6192.168.4.201Worker

服务器具体配置要求如下:

  • 至少2G内存
  • 至少2核CPU
  • 磁盘至少100G

5 系统优化

主机的优化不单纯只是软硬件的优化,基于操作系统的性能优化也是多方面的,可以从几个方面进行衡量,以更好的提高主机的性能。

5.1 关闭SELinux(Master、Worker)

SELinux不关闭的情况下无法实现,会限制ssh免密码登录。

[root@harbor ~]# setenforce 0
[root@harbor ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux

5.2 关闭防火墙(Master、Worker)

防止安装时出现各个组件的端口不能访问的问题。

[root@harbor ~]# systemctl stop firewalld && systemctl disable firewalld       

5.3 时间同步(Master、Worker)

同步时间可以有效解决因时间不同而造成的不同步。

[root@harbor ~]# yum -y install ntp
[root@harbor ~]# ntpdate ntp1.aliyun.com
[root@harbor ~]# timedatectl set-timezone Asia/Shanghai

5.4 修改系统打开文件最大数量(Master、Worker)

放开系统打开文件最大数量,防止因达到上限值而导致的进程终止。

[root@harbor ~]# vi /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535

6 环境准备

两台机器需要事先安装好Docker、Docker-compose,并且将Harbor安装脚本下载到本地。

6.1 安装Docker(Master、Worker)

添加Docker Yum源,安装Docker组件。

[root@harbor ~]# yum install -y yum-utils
[root@harbor ~]# yum-config-manager --add-repo \
               https://download.docker.com/linux/centos/docker-ce.repo
[root@harbor ~]# yum -y install docker-ce docker-ce-cli containerd.io
[root@harbor ~]# systemctl start docker
[root@harbor ~]# systemctl enable docker

6.2 下载Harbor离线安装包(Master、Worker)

在Github下载离线安装包:https://github.com/goharbor/harbor/releases(推荐使用迅雷下载)

下载离线安装包

7 部署Harbor

7.1 配置Harbor(Master、Worker)

将下载的Harbor压缩包上传到Master和Woker节点,修改Harbor配置文件。

[root@harbor ~]# tar -zxvf harbor-offline-installer-v2.0.2.tgz
[root@harbor ~]# cd harbor
[root@harbor harbor]# cp harbor.yml.tmpl  harbor.tml
[root@harbor harbor]# vi harbor.yml
# 修改为当前所在节点的ip
hostname: 192.168.4.200
# 登录界面的密码
harbor_admin_password: tera123
# harbor的版本号
_version: 2.0.2
# 将https相关的配置给注释掉,这里为了简单只使用http,而且也可以在nginx那一层去做https
#https related config
# https:
#  https port for harbor, default is 443
#  port: 443
#  The path of cert and key files for nginx
#  certificate: /your/certificate/path
#  private_key: /your/private/key/path

7.2 安装Harbor(Master、Worker)

准备好配置文件后,安装docker-compose,因为Harbor的安装脚本基于docker-compose去安装的。

[root@harbor harbor]# curl -L \
 "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
[root@harbor harbor]# chmod 755 /usr/local/bin/docker-compose
[root@harbor harbor]# ./install.sh

7.3 访问Harbor

安装完成之后,使用浏览器访问Harbor,可以进入登录页面。默认账户admin。

进入登录页面
项目界面

8 Harbor高可用方案

本次采用的高可用方案是Harbor的主备复制,需要两个Harbor节点。Master和Worker之间能够互相复制,然后通过Nginx代理Harbor Master节点提供外部访问。这里采用的高可用方案是分钟级的,主要是通过Nginx代理Master节点,当Master节点挂掉后手动的修改Nginx配置文件去代理另一个可用节点。

高可用方案一般选用开源的Keepalived+Nginx,而本次方案并没有采用Keepalived的原因主要有两个:

  • 我们的虚机是部署在OpenStack上的,云环境基本无法使用Keepalived,云服务商一般也不支持自定义外网可访问的虚拟IP,当然部署在内网物理服务器上是可以使用Keepalived的。
  • 两个Harbor节点之间的同步是存在延时的,而且镜像通常都比较大,所以这个延迟会非常的明显。一般镜像推送完马上就会调度拉取,所以这个延迟时间一般是不可接受的。如果让Nginx代理两个节点就会出现一会请求A一会请求B的问题,造成镜像Pull/Push不成功。但由于Harbor是给公司内部的开发人员使用,通常可以允许分钟级别的不可用。

9 Harbor高可用部署

Harbor在部署好之后组件中包含了Nginx并且占用了宿主机的80端口,我们通过修改Harbor安装脚本的YAML文件来修改Nginx占用宿主机端口,并且拉取新的Nginx容器反向代理Master节点。Master节点和Worker节点之间配置主从复制,以达到Harbor分钟级高可用的目的。

9.1 删除Harbor容器(Master)

强制删除Master节点创建的所有Harbor容器,容器在创建之前已经做了文件夹的映射,数据不会丢失。

[root@harbor harbor]# docker rm -f `docker ps  |awk '{print $1}' |grep -v CON`

9.2 修改部署文件(Master)

修改YAML文件中Proxy组件Nginx服务的端口映射。

[root@harbor harbor]# vi docker-compose.yml
  proxy:
    image: goharbor/nginx-photon:v2.0.2
    container_name: nginx
    restart: always
    cap_drop:
      - ALL
    cap_add:
      - CHOWN
      - SETGID
      - SETUID
      - NET_BIND_SERVICE
    volumes:
      - ./common/config/nginx:/etc/nginx:z
      - type: bind
        source: ./common/config/shared/trust-certificates
        target: /harbor_cust_cert
    networks:
      - harbor
    dns_search: .
    ports:
      - 8888:8080
    depends_on:
      - registry
      - core
      - portal
      - log
    logging:
      driver: "syslog"
      options:
        syslog-address: "tcp://127.0.0.1:1514"
        tag: "proxy"

9.3 重新部署Harbor容器(Master)

手动使用docker-compose重新部署Harbor容器,不能使用安装脚本部署。

[root@harbor harbor]# docker-compose up -d

9.4 部署Nginx反向代理(Master)

[root@harbor ~]# mkdir nginx
[root@harbor ~]# cd nginx
[root@harbor nginx]# vi nginx.conf
user nginx;
worker_processes 2;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
    worker_connections 1024;
}
stream {
    upstream hub{
        server 192.168.4.200:8888;
    }
    server {
        listen 80;
        proxy_pass hub;
        proxy_timeout 300s;
        proxy_connect_timeout 5s;
    }
} 
[root@harbor nginx]# docker run -itd --net=host --name harbor-nginx \
 -v /root/nginx/nginx.conf:/etc/nginx/nginx.conf nginx

9.5 配置Harbor节点主从复制

浏览器登录Harbor,配置Harbor节点之间的复制功能,使两个节点能够同步镜像数据。

首先到Master节点的”仓库管理”界面中创建一个新的目标,目标是Worker节点。

创建一个新的目标

然后到”复制管理”界面中新建复制规则。

新建复制规则

10 验证

搭建好Harbor之后,测试能否正常使用。将默认的Library项目删除掉,然后创建新的项目。

10.1 创建项目

填写项目名称、访问级别以及项目仓库的存储容量。

新建项目

10.2 Pull/Push镜像(Master、Worker)

在服务器上测试镜像的Pull和Push。由于搭建的私有仓库默认是不受Docker信任的,所以需要修改配置文件让Docker信任该Registry。

[root@harbor ~]# vi /etc/docker/daemon.json
{
  "insecure-registries": ["192.168.4.200"]
}
[root@harbor ~]# systemctl restart docker
[root@harbor ~]# docker login 192.168.4.200
Username: admin
Password: 
Login Succeeded
[root@harbor ~]# docker tag nginx:latest 192.168.4.200/asterfusion/nginx:latest
[root@harbor ~]# docker push nginx:latest 192.168.4.200/asterfusion/nginx:latest

11 Harbor权限管理

11.1 创建用户

在Harbor管理页面创建用户,并且填写相关信息。创建完成之后可以选择设置用户为管理员,之后就可以通过登录此用户来配置管理Harbor。

创建用户
设置管理员

11.2    登录用户拉取镜像

使用刚创建的用户登录,拉取镜像会失败。因为Harbor的权限管理机制,没有经过授权无法随意拉取镜像,我们需要将创建的用户添加到镜像仓库中去,才可以拉取镜像。

[root@harbor ~]# docker login 192.168.4.200
Username: asterfusion
Password: 
Login Succeeded
[root@harbor ~]# docker pull \
192.168.4.200/asterfusion/redis@sha256:2510920e4faef376509a41bbfe58ea62f3e3e1c0dbcfca579581909b279ebaaa
Trying to pull repository 192.168.4.200/asterfusion/redis ... 
unauthorized: unauthorized to access repository: asterfusion/redis, action: pull: unauthorized to access repository: asterfusion/redis, action: pull

11.3    镜像仓库添加用户

在镜像仓库中添加新用户,并且选择用户的角色,在这里我们需要对镜像作Push和Pull操作。

新建成员

11.4    验证

[root@harbor ~]# docker login 192.168.4.200
Username: asterfusion
Password: 
Login Succeeded
[root@harbor ~]# docker pull\
192.168.4.200/asterfusion/redis@sha256:2510920e4faef376509a41bbfe58ea62f3e3e1c0dbcfca579581909b279ebaaa
Trying to pull repository 192.168.4.200/asterfusion/redis ... 
sha256:2510920e4faef376509a41bbfe58ea62f3e3e1c0dbcfca579581909b279ebaaa: Pulling from 192.168.4.200/asterfusion/redis
07cd1d2c25e7: Pull complete 
4319f9523628: Pull complete 
286473b88c0c: Pull complete 
d42081d9071a: Pull complete 
f945dcaa9608: Pull complete 
Digest: sha256:2510920e4faef376509a41bbfe58ea62f3e3e1c0dbcfca579581909b279ebaaa
Status: Downloaded newer image for     
 192.168.4.200/asterfusion/redis@sha256:2510920e4faef376509a41bbfe58ea62f3e3e1c0dbcfca579581909b279ebaaa

12 Harbor镜像漏洞扫描

镜像安全是容器化建设中一个很重要的环节,在Harbor中集成了开源项目Clair的扫描功能,可以帮助用户发现容器镜像中的安全漏洞,及时采取防范措施。

12.1 添加扫描模块(Master)

[root@harbor harbor]# ./prepare –with-clair
[root@harbor harbor]# docker-compose -f docker-compose.yml up -d

12.2 新建扫描器

在审查服务中新建扫描器。

编辑扫描器

12.3 测试扫描

编辑好定时规则之后,我们可以手动进行漏洞扫描

漏洞扫描

12.4 查看扫描结果

可以看到我们的测试镜像中有一个发现了漏洞,通过日志可以看到具体的ERROR信息。

查看扫描结果
日志信息

13 参考文献

Harbor官方文档:https://goharbor.io/docs/2.0.0/install-config/

Docker官方文档:https://docs.docker.com/engine/install/centos/

GitHub仓库地址:https://github.com/goharbor/harbor/wiki

更多内容请参考:A-Lab

配置指导:Rancher-Kubernetes容器化部署

1 Rancher简介

Rancher是一套容器管理平台,它可以帮助组织在生产环境中轻松快捷的部署和管理容器。 Rancher可以轻松地管理各种环境的Kubernetes,满足IT需求并为DevOps团队提供支持。

Kubernetes手动部署非常复杂,Rancher容器化部署相对来说比较简单,并且Rancher支持Web端管理Kubernetes,而Kubernetes原生的Dashboard只提供监控。

2 Kubernetes简介

Kubernetes已成为容器集群管理标准,通过YAML文件来管理配置应用程序容器和其他资源。Kubernetes执行诸如调度,扩展,服务发现,健康检查,密文管理和配置管理等功能。

3 组件

  一个Rancher-Kubernetes集群由多个节点组成:

  • Etcd database:通常在一个节点上运行一个etcd实例,存储K8s中IP地址等信息
  • Rancher-server:Rancher管理平台,用户通过Rancher Web端配置K8s集群
  • Master nodes:K8s主节点是无状态的,用于运行API Server,调度服务和控制器服务
  • Worker nodes:K8s工作负载节点,运行容器

4 Rancher-K8s对比源码K8s

优点:

  • 采用图形化方式:易用的Web管理界面,在Docker易用性的基础上,再一次降低了使用容器技术部署容器应用的难度
  • 支持多种调度器:通过环境模板,很容易地创建和部署Swarm、K8S容器集群管理调度平台
  • 管理主机集群:管理对象是多台主机的集群,而不仅仅是单台容器主机,创建和管理几台、几十台应用服务器集群,只需要复制粘贴就解决了
  • 内置应用商店:使用其中的应用模板,创建一个WordPress博客系统,只需点点鼠标,部署简单
  • 资源弹性分配内置应用负载均衡器,“服务”最小只需1个容器实例,当负载不够/或过剩时,只需点点鼠标,增加/减少“服务”中容器的实例数,即可解决问题,应用系统具有天生的弹性扩容能力。

缺点:

  • K8S部署的问题由于国内网络和国外网络访问的问题,在国内部署K8S集群,有点不方便
  • 应用商店的问题默认的Rancher官方认证和社区贡献的应用商店内容有限,应用还不够丰富,基本上都是网络和存储等基础的应用;个别应用部署后,无法通过相同的操作,再部署同样的另一套应用,比如Rancher NFS
  • 故障拍错的问题:因为Rancher-K8s是一键打包部署好的,组件容器化,如果遇到问题会为排障带来很大的困难

5 环境准备

本次部署三台Server,一台作为Rancher-server,一台作为Master,另一台为Worker节点。服务器具体配置如下:

  • 1个千兆网口
  • 至少8G内存
  • 磁盘至少40G
  • Rancher-server:192.168.4.210
  • Master:192.168.4.211
  • Worker:192.168.4.212

6 部署过程

6.1 关闭SELinux 【所有节点】

SeLinux不关闭会发生无法访问的情况。

[root@localhost  ~]# setenforce 0
[root@localhost  ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux

6.2 关闭防火墙【所有节点】

防止安装时出现各个组件的端口不能访问的问题。

[root@localhost  ~]#systemctl stop firewalld && systemctl disable firewalld                          

6.3 设置主机名【所有节点】

Rancher-server。

[root@localhost ~]# hostname rancher
[root@localhost ~]# echo “rancher” > /etc/hostname

Master

[root@localhost ~]# hostname master
[root@localhost ~]# echo “master” > /etc/hostname

Worker

[root@localhost ~]# hostname worker
[root@localhost ~]# echo “worker” > /etc/hostname

6.4 安装Git【Rancher节点】

安装Git拉取GitHub文件。

[root@localhost  ~]# yum -y install epel-release
[root@localhost  ~]# yum -y install git
[root@localhost  ~]# git clone https://github.com/yx464050145/Ansible-Rancher.git

6.5 安装Ansible【Rancher节点】

Rancher使用Ansible脚本自动化安装,并且修改Ansible配置文件。

[root@localhost  ~]# yum -y install ansible
[root@localhost  ~]# vi /etc/ansible/ansible.cfg
[defaults]
host_key_checking = False

6.6 修改Rancher-ansible配置文件【Rancher节点】

[root@localhost  ~]# vi /root/Ansible-Rancher/inventory/hosts
[rancher]
192.168.4.210 ansible_ssh_user='root' ansible_ssh_pass='tera123'   
[master]
192.168.4.211 ansible_ssh_user='root' ansible_ssh_pass='tera123'
[worker]
192.168.4.212 ansible_ssh_user='root' ansible_ssh_pass='tera123'

[root@localhost  ~]# vi /root/Ansible-Rancher/rancher_server/vars/main.yml
# defaults file for rancher
rancher_name: 'rancher_server'
rancher_port: 80
rancher_image: rancher/rancher:stable
rancher_data: /var/rancher
rancher_ssl_ports: 443
rancher_url: https://192.168.4.210
rancher_admin_password: "tera123"
validate_certs: false

[root@localhost  ~]# vi /root/Ansible-Rancher/rancher_master/vars/main.yml
# defaults file for rancher
rancher_url: https://192.168.4.210
rancher_admin_password: "tera123"
validate_certs: false
rancher_network_provider: "calico"
rancher_cluster_name: asterfusion
rancher_master_role: "--etcd --controlplane"
rancher_project_name: "asterfusion"

[root@localhost  ~]# vi /root/Ansible-Rancher/rancher_worker/vars/main.yml
rancher_url: "https://192.168.4.210"
rancher_admin_password: "tera123"
validate_certs: false
rancher_network_provider: "calico"
rancher_cluster_name: asterfusion
rancher_worker_role: "--worker"

6.7 Ansible-playbook部署Rancher集群【Rancher节点】

[root@localhost  ~]# cd /root/Ansible-Rancher
[root@localhost  ~]# ansible-playbook -i inventory/hosts rancher.yml

6.8 Rancher Web

Rancher Web

6.9 Rancher K8s集群

图中可以看出K8s集群部署完成,Master上部署了etcd、control,Worker部署容器。

K8s集群部署

6.10 部署Pod

  • 名称:Pod名字(必填)
  • Docker镜像:容器镜像(必填)
  • 端口映射:端口映射规则和网络模式,如果不需要外网访问可以不填(选填)
  • 类型:Pod类型(必填)

下图Nginx Pod已经部署好了

Nginx Pod部署

6.11 Kubelet命令行

Kubelet命令行

6.12 报错问题

部署过程中如果速度太慢并且报错,是因为网络原因导致拉取镜像失败或者超时。可以选择拷贝镜像到各个节点中免去拉取镜像的过程。在部署完成后耐心等待所有容器组件状态正常才可部署Pod。

7 参考资料

  1. Rancher官网:https://rancher.com/docs/rancher/v2.x/en
  2. Kubernetes官网:https://kubernetes.io/

更多内容请参考:A-Lab

配置指导:OpenStack Zun部署

1 目标与物理网络拓扑

本文主要描述在现有OpenStack(rocky版)平台上如何扩展安装Zun功能组件,实现容器管理服务。

涉及物理拓扑,如图1所示:

物理拓扑
图1:物理网络拓扑

部署过程中所涉及到的设备、接口及管理网口的IP地址如下表所示:

设备名称接口IP地址备注
Switch-A管理口192.168.0.254三层交换机
Switch-B管理口192.168.4.1二层交换机
Switch-C管理口192.168.5.1二层交换机
Server-1管理口192.168.4.144 
Server-2管理口192.168.5.145 
表1:设备管理口列表

2 硬件与软件环境

部署环境中涉及到的硬件和软件如表2和表3所示:

名称型号硬件指标数量备注
服务器 1.至少8G内存
2.磁盘不少于500G
2Server-1计算节点+存储节点
Server-2 控制节点+网络节点
表2:硬件环境

软件版本备注
操作系统Centos7.6安装时选择Compute Node 模式,根目录/至少500G
OpenStackRocky 
表3:软件环境

3 Zun简介

Zun是OpenStack容器服务。它旨在为运行应用程序容器提供API服务,而无需管理服务器或集群。

它集成了Neutron、Cinder、Keystone等核心OpenStack服务,实现了 容器的快速普及。通过这种方式,OpenStack的所有原始网络、存储和识别验证工具都应用于容器系统,使容器能够满足安全性和合规性要求。

目前,OpenStack拥有以下支持容器技术的主流解决方案:

  • Nova Docker驱动程序

该解决方案将容器作为VM运行。添加Nova Docker驱动程序以执行与常规VM类似的操作, 以启动、停止或创建Docker容器。由于Docker和VM之间的差异,这种操作模式将禁用容器的许多功能,例如容器相关和端口映射。

  • Magnum

Magnum是一个OpenStack服务,提供容器集群部署功能。Magnum通过Heat部署VM和裸金属,形成集群,然后调用COE接口完成容器的部署。在Magnum成立之初,该项目以“容器即服务”(CaaS)为目标。在以后的开发过程中,Magnum的大部分功能都集中在容器的集群部署上。

  • Zun

Zun将容器作为一种OpenStack资源进行管理,并集成了OpenStack的其他服务,为用户提供统一、简化的API。用户可以通过API创建和管理容器,而不需要考虑不同容器技术之间的差异。

集成OpenStack服务的优点是用户可以借助OpenStack的现有功能扩展容器的功能。例如,默认情况下,Zun容器可以使用Neutron分配的IP地址,并可以使用Keystone提供的身份验证服务。使用Zun和Neutron,用户可以在Nova实例所在的隔离网络环境中创建容器。VM的Neutron功能(安全组、QoS)也可用于Zun容器。在实际业务中,经常有需要长时间保存数据的场景。常用方法是使用外部服务为容器提供持久卷。Zun通过与OpenStack Cinder 集成解决了这个问题。创建容器时,用户可以选择将Cinder卷安装到容器中。Cinder卷可以是租户中现有的或新创建的卷。每个卷都将绑定到容器文件系统路径,并且将保留该路径下存储的数据。对于编排,与提供内置编排的其他容器平台不同,Zun使用外部编排系统来实现此目的,例如Heat和Kubernetes。借助外部编排工具,最终用户可以使用该工具提供的DSL来定义容器化应用程序。使用Heat,用户还可以定义由容器资源和OpenStack资源组成的资源,例如Neutron负载均衡器、浮动IP、Nova实例等。

Zun和Kubernetes是互补的。事实上,Zun社区正在积极推动与Kubenetes的整合。目前,Zun与COE的整合工作主要集中在Kubenetes上,这将使容器更易于部署、管理和扩展。但是,在OpenStack上使用Kubernetes仍然需要用户手动部署底层基础设施,例如虚拟服务器集群。用户负责初始容量规划,例如确定VM集群的大小和维护正在运行的VM集群。

无服务器容器技术或解决方案(如AWS Fargate、Azure Container Instance(ACI)和 OpenStack Zun)的出现为在云上运行容器提供了可行的替代方案。无服务器方法允许用户按需运行容器,而无需事先创建或管理自己的集群。

Zun将使用Kubernetes作为业务流程层,Kubernetes将使用OpenStack Zun提供“无服务器”容器。

Zun提出了Container和Capsule的概念。Container负责集成Docker或其他容器引擎技术。 Capsule的概念有点像Kubernetes Pod,它代表一组容器。Capsule用于对需要彼此紧密合作 以实现服务目标的多个容器进行分组。

Zun不准备实现COE提供的许多高级功能(例如容器保持活动、负载均衡),而是专注于提供基本容器操作(CRUD)并保持与OpenStack的紧密集成。

与Nova Docker驱动程序比较,Zun旨在解决Nova Docker驱动程序解决方案的问题。它独立于Nova实现了Docker的部署调度框架,并与Glance、Neutron、Cinder和其他组件集成,但没有实现Container Orchestration Engines(COE)的部署调度。Nova-docker通过 Nova API访问容器,Zun不受Nova API的限制。

与Magnum相比,Zun和Magnum之间的区别在于Zun专注于提供用于管理容器的API,而 Magnum提供部署和管理容器编排引擎(COE)的API。

Zun 的 基 本 架 构 的 基 本 架 构 以下Zun架构图很好地说明了Zun和OpenStack组件之间的关系。

Zun架构图
图2: Zun架构图

解释:

  • Zun API:处理REST请求和检查输入参数
  • Zun Compute:资源调度和容器管理
  • Keystone:OpenStack的认证组件
  • Neutron:为容器提供网络
  • Glance:存储docker镜像(如果不使用glance,可以使用DockerHub)
  • Kuryr:连接容器网络和Neutron的插件

4 安装步骤

[root@controller ~] 表示在控制节点上执行

[root@compute ~] 表示在计算节点上执行

4.1   创建数据库

  • 创建数据库并授权:
[root@controller ~]# mysql -uroot -p
MariaDB [(none)]> CREATE DATABASE zun;
MariaDB [(none)]> GRANT ALL PRIVILEGES ON zun.* TO 'zun'@'localhost' \
  IDENTIFIED BY 'ZUN_PASS';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON zun.* TO 'zun'@'%' \
  IDENTIFIED BY 'ZUN_PASS';

注:帐号密码根据自己的情况修改

4.2 创建openstack用户、服务凭据、API端点:

  • 在安装和配置Zun之前,必须创建用户、服务凭据和API端点:
[root@controller ~]#source admin-openrc
[root@controller ~]#openstack user create --domain default --password-prompt zun
[root@controller ~]#openstack role add --project service --user zun admin
[root@controller ~]#openstack service create --name zun \
--description "Container Service" container
[root@controller ~]#openstack endpoint create --region RegionOne \
container public http://controller:9517/v1
[root@controller ~]#openstack endpoint create --region RegionOne \
container internal http://controller:9517/v1
[root@controller ~]#openstack endpoint create --region RegionOne \
container admin http://controller:9517/v1

4.3 在controller节点上添加kuryr-libnetwork用户

  • 创建kuryr用户
[root@controller ~]#source admin-openrc
[root@controller ~]#openstack user create --domain default --password-prompt kuryr
  • 添加角色
[root@controller ~]#openstack role add --project service --user kuryr admin

4.4 在compute节点安装kuryr-libnetwork

kuryr-libnetwork是运行在Libnetwork框架下的一个plugin。Libnetwork定义了一个灵活的模型,使用local或者remotedriver来向container提供网络服务。kuryr-libnetwork就是Libnetwork的一个remotedriver实现。

kuryr-libnetwork主要实现了两个功能:NetworkDriver和IPAMDriver。

  • 添加内核参数
[root@compute ~]# vi /etc/sysctl.conf
net.ipv4.ip_forward = 1 
[root@compute ~]#sysctl -p
net.ipv4.ip_forward = 1
  • 安装启动docker
[root@compute ~]# yum -y install yum-utils 
[root@compute ~]# yum-config-manager --add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 
[root@compute ~]#yum install docker-ce
[root@compute ~]# systemctl enable docker
[root@compute ~]#systemctl start docker
  • 创建用户
[root@controller ~]#groupadd --system kuryr
[root@controller ~]#useradd --home-dir "/var/lib/kuryr" --create-home --system --shell /bin/false -g kuryr kuryr
  • 创建目录
[root@controller ~]#mkdir -p /etc/kuryr
[root@controller ~]#chown kuryr:kuryr /etc/kuryr
  • 安装kuryr-libnetwork
[root@compute ~]#cd /var/lib/kuryr
[root@compute ~]#git clone -b stable/rocky https://opendev.org/openstack/kuryr-libnetwork.git
[root@compute ~]#chown -R kuryr:kuryr kuryr-libnetwork
[root@compute ~]#cd kuryr-libnetwork
[root@compute ~]#pip install -r requirements.txt 
[root@compute ~]#python setup.py install
  • 生成示例配置文件
[root@compute ~]# su -s /bin/sh -c "./tools/generate_config_file_samples.sh" kuryr
[root@compute ~]# su -s /bin/sh -c "cp etc/kuryr.conf.sample /etc/kuryr/kuryr.conf" kuryr
  • 编辑配置文件,添加以下内容
[root@compute ~]#vi /etc/kuryr/kuryr.conf
[DEFAULT]
bindir = /usr/libexec/kuryr
[neutron]
www_authenticate_uri = http://controller:5000
auth_url = http://controller:5000 
username = kuryr
user_domain_name = default
password = kuryr
project_name = service
project_domain_name = default
auth_type = password
  • 创建启动文件
[root@compute ~]#vi /etc/systemd/system/kuryr-libnetwork.service
[Unit]
Description = Kuryr-libnetwork - Docker network plugin for Neutron

[Service]
ExecStart = /usr/bin/kuryr-server --config-file /etc/kuryr/kuryr.conf
CapabilityBoundingSet = CAP_NET_ADMIN

[Install]
WantedBy = multi-user.target
  • 启动服务
[root@compute ~]#systemctl enable kuryr-libnetwork
[root@compute ~]#systemctl start kuryr-libnetwork
[root@compute ~]#systemctl restart docker

4.5   在controller节点上安装zun服务

  • 创建用户、组:
[root@controller ~]#groupadd --system zun
[root@controller ~]#useradd --home-dir "/var/lib/zun"  \
--create-home \
--system  \
--shell /bin/false  \
-g zun  \
zun
  •  创建目录
[root@controller ~]#mkdir -p /etc/zun
[root@controller ~]# chown zun:zun /etc/zun
  • 安装zun
[root@controller ~]# yum install python-pip git python-devel libffi-devel gcc git
[root@controller ~]#cd /var/lib/zun
[root@controller ~]#git clone -b stable/rocky  https://opendev.org/openstack/zun.git
[root@controller ~]#chown -R zun:zun zun
[root@controller ~]#cd zun
[root@controller ~]#pip install pbr --no-index -f file:///var/lib/zun/zun/base/
[root@controller ~]# pip install -r requirements.txt 
[root@controller ~]# python setup.py install
[root@compute ~]#pip install zun==2.1.0
  • 生成示例配置文件
[root@controller ~]#su -s /bin/sh -c "oslo-config-generator --config-file etc/zun/zun-config-generator.conf" zun
[root@controller ~]#su -s /bin/sh -c "cp etc/zun/zun.conf.sample /etc/zun/zun.conf" zun
  • 复制api-paste.ini配置文件
[root@controller ~]#su -s /bin/sh -c "cp etc/zun/api-paste.ini /etc/zun" zun
  • 编辑配置文件
[root@controller ~]#vi /etc/zun/zun.conf
[DEFAULT]
transport_url = rabbit://openstack:tera123@controller
log_dir = /var/log/zun
[api]
Host_ip = 192.168.4.144
port = 9517
[database]
connection = mysql+pymysql://zun:ZUN_PASS@controller/zun
[keystone_auth]
memcached_servers = controller:11211
www_authenticate_uri = http://controller:5000
project_domain_name = default
project_name = service
user_domain_name = default
password = zun
username = zun
auth_url = http://controller:5000
auth_type = password
auth_version = v3
auth_protocol = http
service_token_roles_required = True
endpoint_type = internalURL
[keystone_authtoken]
memcached_servers = controller:11211
www_authenticate_uri = http://controller:5000
project_domain_name = default
project_name = service
user_domain_name = default
password = zun
username = zun
auth_url = http://controller:5000
auth_type = password
auth_version = v3
auth_protocol = http
service_token_roles_required = True
endpoint_type = internalURL
[oslo_concurrency]
lock_path = /var/lib/zun/tmp
[oslo_messaging_notifications]
driver = messaging
[websocket_proxy]
wsproxy_host = 192.168.4.144
wsproxy_port = 6784
  • 创建日志目录
[root@controller ~]#mkdir -p /var/log/zun
[root@controller ~]#chown zun:zun -R /var/log/zun
  • 填充数据库
[root@controller ~]#su -s /bin/sh -c "zun-db-manage upgrade" zun
  • 创建启动文件
[root@controller ~]#vi /etc/systemd/system/zun-api.service
[Unit]
Description = OpenStack Container Service API

[Service]
ExecStart = /usr/bin/zun-api
User = zun

[Install]
WantedBy = multi-user.target

[root@controller ~]# vi /etc/systemd/system/zun-wsproxy.service
[Unit]
Description = OpenStack Container Service Websocket Proxy

[Service]
ExecStart = /usr/bin/zun-wsproxy
User = zun

[Install]
WantedBy = multi-user.target
  • 启动服务
[root@controller ~]# systemctl enable zun-api  zun-wsproxy
[root@controller ~]# systemctl start zun-api  zun-wsproxy
[root@controller ~]# systemctl status zun-api  zun-wsproxy

4.6 在compute节点上安装zun服务

  • 创建用户、组:
[root@compute ~]#groupadd --system zun
[root@compute ~]#useradd --home-dir "/var/lib/zun"  \
--create-home \
--system  \
--shell /bin/false  \
-g zun  \
zun
  •  创建目录
[root@compute ~]#mkdir -p /etc/zun
[root@compute ~]#chown zun:zun /etc/zun
  • 安装zun
[root@compute ~]# yum install python-pip git python-devel libffi-devel gcc numactl  
[root@compute ~]#cd /var/lib/zun
[root@compute ~]#git clone -b stable/rocky https://opendev.org/openstack/zun.git 
[root@compute ~]#chown -R zun:zun zun
[root@compute ~]#cd zun
[root@compute ~]#pip install -r requirements.txt
[root@compute ~]#python setup.py install
[root@compute ~]#pip install zun==2.1.0
  • 生成示例配置文件
[root@compute ~]#su -s /bin/sh -c "oslo-config-generator --config-file etc/zun/zun-config-generator.conf" zun
[root@compute ~]#su -s /bin/sh -c "cp etc/zun/zun.conf.sample /etc/zun/zun.conf" zun
[root@compute ~]#su -s /bin/sh -c "cp etc/zun/rootwrap.conf /etc/zun/rootwrap.conf" zun
[root@compute ~]#su -s /bin/sh -c "mkdir -p /etc/zun/rootwrap.d" zun
[root@compute ~]#su -s /bin/sh -c "cp etc/zun/rootwrap.d/* /etc/zun/rootwrap.d/" zun
  • 配置zun用户
[root@compute ~]#echo "zun ALL=(root) NOPASSWD: /usr/local/bin/zun-rootwrap /etc/zun/rootwrap.conf *" | sudo tee /etc/sudoers.d/zun-rootwrap
  • 编辑配置文件
[root@compute ~]#vi /etc/zun/zun.conf
[DEFAULT]
transport_url = rabbit://openstack: tera123@controller
state_path = /var/lib/zun
log_dir = /var/log/zun
[database]
connection = mysql+pymysql://zun:ZUN_PASS@controller/zun
[keystone_auth]
memcached_servers = controller:11211
www_authenticate_uri = http://controller:5000
project_domain_name = default
project_name = service
user_domain_name = default
password = zun
username = zun
auth_url = http://controller:5000
auth_type = password
auth_version = v3
auth_protocol = http
service_token_roles_required = True
endpoint_type = internalURL
[keystone_authtoken]
memcached_servers = controller:11211
www_authenticate_uri= http://controller:5000
project_domain_name = default
project_name = service
user_domain_name = default
password = zun
username = zun
auth_url = http://controller:5000
auth_type = password
[websocket_proxy]
base_url = ws://controller:6784/
[oslo_concurrency]
lock_path = /var/lib/zun/tmp

注意:如果想把容器和实例都运行在这台计算节点上,上面的配置文件要添加这项配置

[compute]

host_shared_with_nova = true

  • 创建日志目录
[root@controller ~]#mkdir -p /var/log/zun
[root@controller ~]#chown zun:zun -R /var/log/zun
  • 配置docker和kury

创建docker配置文件夹

[root@compute ~]#mkdir -p /etc/systemd/system/docker.service.d

创建docker配置文件

[root@compute ~]# vi /etc/systemd/system/docker.service.d/docker.conf
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --group zun -H tcp://compute:2375 -H unix:///var/run/docker.sock --cluster-store etcd://controller:2379

重启docker

[root@compute ~]#systemctl daemon-reload
[root@compute ~]#systemctl restart docker

编辑kuryr配置文件

[root@compute ~]#mkdir -p /etc/kuryr
[root@compute ~]#vi  /etc/kuryr/kuryr.conf
[DEFAULT]
capability_scope = global
process_external_connectivity = False

重启kuryr

[root@compute ~]#systemctl restart kuryr-libnetwork
  • 配置containerd

生成containerd配置文件

[root@compute ~]# containerd config default > /etc/containerd/config.toml

编辑容器配置文件

将[grpc]项目中的gid配成zun用户的组id

[root@compute ~]#vi /etc/containerd/config.toml
[grpc]
  ...
  gid = ZUN_GROUP_ID

说明:获取用户组id的方法

getent group zun | cut -d: -f3

重启containerd

[root@compute ~]#systemctl restart containerd
  • 创建启动文件
[root@compute ~]#vi /etc/systemd/system/zun-compute.service
[Unit]
Description = OpenStack Container Service Compute Agent

[Service]
ExecStart = /usr/bin/zun-compute
User = zun

[Install]
WantedBy = multi-user.target
  • 启动zun-compute
[root@compute ~]#systemctl enable zun-compute 
[root@compute ~]#systemctl start zun-compute 
[root@compute ~]#systemctl status zun-compute

4.7 在controller节点安装zun-ui

  • 安装zun-ui
[root@controller ~]#pip install zun-ui==2.0.0
  • 复制文件
[root@controller ~]#cd /usr/lib/python2.7/site-packages/zun_ui
[root@controller ~]#cp enabled/*  \
 /usr/share/openstack-dashboard/openstack_dashboard/local/enabled/
  • 重启服务
[root@controller ~]#systemctl restart httpd memcached

5 结果验证

在compute节点创建kuryr网络及创建容器

  • 创建kuryr网络
[root@controller ~]#docker network create --driver kuryr --ipam-driver kuryr --subnet 10.10.0.0/16 --gateway=10.10.0.1  test_net
  • 查看网络
[root@controller ~]#docker network ls
  • 创建容器
[root@controller ~]#docker run --net test_net cirros ifconfig

在controller节点验证

  • 准备验证
[root@controller ~]# pip install python-zunclient
[root@controller ~]#source admin-openrc
  • 查看网络
[root@controller ~]#openstack network list
  • 获取网络id
[root@controller ~]#export NET_ID=$(openstack network list | awk '/ selfservice / { print $2 }')
  • 创建容器
[root@controller ~]#openstack appcontainer run --name container --net network=$NET_ID cirros ping 8.8.8.8
  • 查看容器列表
[root@controller ~]#openstack appcontainer list
  • 执行sh命令
[root@controller ~]#openstack appcontainer exec --interactive container /bin/sh
  • 停止容器
[root@controller ~]#openstack appcontainer stop container
  • 删除容器
[root@controller ~]#openstack appcontainer delete container

6 参考资料

更多内容请参考:A-Lab

配置指导:OpenStack-Ironic 安装部署

OpenStack-Ironic源码安装部署方案

1 Ironic简介

裸金属节点特指没有部署操作系统的物理服务器,相对于虚拟机,裸金属节点具有更强的计算能力、资源独占以及安全隔离等优点。Ironic旨在为用户提供自助式的裸金属管理服务,Ironic既可以独立使用,也可以与 OpenStack集成。Ironic与OpenStack集成提供裸金属管理服务,允许用户像管理虚拟机一样管理裸金属节点,部署裸机就像是部署虚拟机一样简单,为用户提供了多租户网络的裸金属云基础设施。

2 Ironic架构图

Ironic架构图

3 Ironic必要组件

  • Ironic API:提供北向RESTful API
  • Ironic Conductor:完成裸机管理服务的绝大部分工作:添加、编辑、删除裸机;开/关裸机电源;提供、部署清理裸机等
  • Ironic Python Agent:简称IPA,是一个运行在RAMDisk之上的Python服务,暴露RESTful API接收Ironic Conductor的远程访问,完成裸机的相关操作

4 Ironic依赖服务

  • TFTP:TFTP是用来下载远程文件的最简单网络协议,它基于UDP协议而实现
  • PXE:PXE是一种引导方式,进行PEX安装的必要条件是在要安装的计算机中必须包含一个PXE支持的网卡,PXE协议可以使计算机通过网络启动
  • IPMI:IPMI是智能型平台管理接口,其核心是一个专用芯片BMC,其并不依赖于服务器的处理器、BIOS或操作系统来工作,是一个单独在系统内运行的无代理管理子系统,只要有BMC与IPMI固件便可开始工作,而BMC通常是一个安装在服务器主板上的独立的板卡。用户可以利用IPMI监视服务器的物理健康特征,如温度、电压、风扇工作状态、电源状态等

5 硬件配置

服务器具体配置要求如下:

  • 2个千兆网口
  • 至少8G内存
  • 磁盘至少40G

6 系统优化

主机的优化不单纯只是软硬件的优化,基于操作系统的性能优化也是多方面的,可以从几个方面进行衡量,以更好的提高主机的性能。

6.1 关闭SELinux(控制节点、BareMetal节点)

SELinux不关闭的情况下无法实现,会限制ssh免密码登录。

[root@localhost  ~]#setenforce 0
[root@localhost  ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux

6.2 关闭防火墙(控制节点、BareMetal节点)

防止安装时出现各个组件的端口不能访问的问题。

[root@localhost  ~]#systemctl stop firewalld && systemctl disable firewalld                          

6.3 时间同步(控制节点、BareMetal节点)

同步时间可以有效解决因时间不同而造成的不同步。

[root@localshot  ~]# yum -y install ntp
[root@localhost  ~]# ntpdate ntp1.aliyun.com
[root@localhost  ~]# timedatectl set-timezone Asia/Shanghai

6.4 修改系统打开文件最大数量(控制节点、BareMetal节点)

放开系统打开文件最大数量,防止因达到上限值而导致的进程终止。

[root@localhost  ~]# vi /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535

6.5 安装OpenStack国内yum源(BareMetal节点)

安装阿里的OpenStack yum源可以加快各组件的下载速度。

[root@localhost  ~]# cat << EOF >> /etc/yum.repos.d/openstack.repo
[openstack-rocky]
name=openstack-rocky
baseurl=https://mirrors.aliyun.com/centos/7/cloud/x86_64/openstack-rocky/
enabled=1
gpgcheck=0
[qume-kvm]
name=qemu-kvm
baseurl= https://mirrors.aliyun.com/centos/7/virt/x86_64/kvm-common/
enabled=1
gpgcheck=0
EOF

6.6 降低Swap分区使用率(控制节点、BareMetal节点)

现在服务器的内存一般是上百GB,所以我们可以把这个参数值设置的低一些(如10-30之间),让操作系统尽可能的使用物理内存,降低系统对swap的使用,从而提高宿主机系统和虚拟机的性能。

[root@localhost  ~]# cat << EOF >> /etc/yum.repos.d/openstack.repo
[openstack-rocky]
name=openstack-rocky
baseurl=https://mirrors.aliyun.com/centos/7/cloud/x86_64/openstack-rocky/
enabled=1
gpgcheck=0
[qume-kvm]
name=qemu-kvm
baseurl= https://mirrors.aliyun.com/centos/7/virt/x86_64/kvm-common/
enabled=1
gpgcheck=0
EOF

7 OpenStack环境验证(控制节点)

Bare Metal服务是各个组件的集合,这些组件为管理和配置物理机提供支持,在部署Bare Metal之前必须要确保已经设置了Keystone、Image、Nova、Neutron等服务。Bare Metal通常在一个独立的计算节点上运行。

7.1 验证Keystone

[root@controller ~]# source admin-openrc
[root@controller ~ ]# openstack user list

命令行展示

7.2 验证Glance

[root@controller ~]# wget http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img
[root@controller ~]# openstack image create "cirros" --file cirros-0.3.4-x86_64-disk.img --disk-format qcow2 --container-format bare --public

7.3 验证Nova

[root@controller ~]# openstack compute service list
命令行展示

7.4 验证Endpoint

[root@controller ~]# openstack endpoint list
命令行展示

7.5 验证Neutron

[root@controller ~]# openstack  network agent list
命令行展示

8 部署Ironic(控制节点、Bare Metal)

8.1 MySQL中创建库和权限(控制节点)

在数据库中创建Ironic库,并且授予用户访问库的权限。

[root@localhost ~]# mysql -uroot -p
MariaDB [(none)]> CREATE DATABASE ironic CHARACTER SET utf8;
MariaDB [(none)]> GRANT ALL PRIVILEGES ON ironic.* TO 'ironic'@'localhost' identified by 'tera123';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON ironic.* TO 'ironic'@'%' identified by 'tera123';

8.2 添加Ironic用户及其鉴权信息(控制节点)

[root@controller ~]# openstack service create --name ironic \
--description "Ironic baremetal provisioning service" baremetal
[root@controller ~ ]# openstack user create --domain default --password-prompt ironic
[root@controller ~]# openstack role add --project service --user ironic admin
[root@controller ~]# openstack endpoint create --region RegionOne baremetal admin\
http://192.168.5.221:6385
[root@controller ~]#openstack endpoint create –region RegionOne baremetal public \
http://192.168.5.221:6385
[root@controller ~]#openstack endpoint create --region RegionOne baremetal internal \
http://192.168.5.221:6385

8.3 安装软件包(Bare Metal)

[root@bare ~]# yum install openstack-ironic-api openstack-ironic-conductor python-ironicclient -y

8.4 配置Ironic配置文件(Bare Metal)

此次Ironic-api和Ironic-conductor同节点部署。

[root@localhost ~]# vi /etc/ironic/ironic.conf
[DEFAULT]
my_ip=192.168.4.221
transport_url = rabbit://openstack:tera123@192.168.4.220
auth_strategy = keystone
[database]
connection=mysql+pymysql://ironic:tera123@192.168.4.220/ironic?charset=utf8
[conductor]
automated_clean = false
clean_callback_timeout = 1800
rescue_callback_timeout = 1800
soft_power_off_timeout = 600
power_state_change_timeout = 30
power_failure_recovery_interval = 300
[glance]
url = http://192.168.4.220:9292
auth_url = http://192.168.4.220:5000
auth_type = password
project_domain_name = default
user_domain_name = default
region_name = RegionOne
project_name = service
username = glance
password = tera123
[service_catalog]
region_name = RegionOne
project_domain_id = default
user_domain_id = default
project_name = service
password = tera123
username = ironic
auth_url = http://192.168.4.220:5000
auth_type = password
[keystone_authtoken]
auth_type=password
www_authenticate_uri = http://192.168.4.220:5000
auth_url = http://192.168.4.220:5000
username=ironic
password=tera123
project_name=service
project_domain_name=default
user_domain_name=default
[neutron]
auth_type = password
auth_url = http://192.168.4.220:5000
username=ironic
password=tera123
project_name=service
project_domain_id=default
user_domain_id=default
region_name = RegionOne
valid_interfaces=public

8.5 同步Ironic数据库并启动服务(Bare Metal)

[root@bare ~]# ironic-dbsync --config-file /etc/ironic/ironic.conf create_schema
[root@bare ~]# systemctl enable openstack-ironic-api openstack-ironic-conductor 
[root@bare ~]# systemctl start openstack-ironic-api openstack-ironic-conductor 

8.6 安装Nova Compute(Bare Metal)

[root@bare ~]# yum install openstack-nova-compute -y

8.7 配置Nova配置文件(Bare Metal、控制节点)

修改控制节点和Bare Metal的nova.conf配置文件。

Bare Metal:
[DEFAULT]
transport_url = rabbit://openstack:tera123@192.168.5.220
my_ip=192.168.5.221
use_neutron=true
compute_driver=ironic.IronicDriver
firewall_driver=nova.virt.firewall.NoopFirewallDriver
reserved_host_cpus=0
[filter_scheduler]
track_instance_changes=False
[scheduler]
discover_hosts_in_cells_interval=120
[ironic]
api_retry_interval = 5
api_max_retries = 300
auth_type=password
auth_url=http://192.168.5.220:5000/v3
project_name=service
username=ironic
password=tera123
project_domain_name=default
user_domain_name=default
[placement]
region_name = RegionOne
project_domain_name = Default
project_name = service
auth_type = password
user_domain_name = Default
auth_url = http://192.168.5.220:5000/v3
username = placement
password = tera123
[neutron]
url = http://192.168.5.220:9696
auth_url = http://192.168.5.220:5000
auth_type = password
project_domain_name = default
user_domain_name = default
region_name = RegionOne
project_name = service
username = neutron
password = tera123

控制节点:
[DEFAULT]
my_ip=192.168.5.220
use_neutron=true
firewall_driver=nova.virt.firewall.NoopFirewallDriver
enabled_apis=osapi_compute,metadata
transport_url=rabbit://openstack:tera123@192.168.5.220
compute_driver=ironic.IronicDriver
reserved_host_memory_mb=0
[scheduler]
discover_hosts_in_cells_interval=120
[api]
auth_strategy=keystone
[api_database]
connection=mysql+pymysql://nova:tera123@192.168.5.220/nova_api
[database]
connection= mysql+pymysql://nova:tera123@192.168.5.220/nova
[glance]
api_servers= http://192.168.5.220:9292
[keystone_authtoken]
www_authenticate_uri = http://192.168.5.220:5000
auth_url=http://192.168.5.220:5000/v3
memcached_servers= 192.168.5.220:11211
auth_type=password
project_domain_name = Default
user_domain_name = Default
project_name = service
username = nova
password = tera123
[placement]
region_name = RegionOne
user_domain_name = Default
auth_type=password
auth_url=http://192.168.5.220:5000/v3
project_name=service
project_domain_name=Default
username=placement
password=tera123
[placement_database]
connection= mysql+pymysql://placement:tera123@192.168.5.220/placement
[scheduler]
discover_hosts_in_cells_interval= 300         
[vnc]
enabled=true
server_listen=$my_ip
server_proxyclient_address=$my_ip
[neutron]
url=http://192.168.5.220:9696
auth_type=password
auth_url=http://192.168.5.220:5000
project_name=service
project_domain_name=default
username=neutron
user_domain_name=default
password=tera123
region_name=RegionOne
service_metadata_proxy = true
metadata_proxy_shared_secret = tera123
[ironic]
auth_type=password
auth_url=http://192.168.5.220:5000/v3
project_name=service
username=ironic
password=tera123
project_domain_name=Default
user_domain_name=Default

8.8 注册Cell并启动Nova服务(控制节点、Bare Metal)

[root@controller ~]# nova-manage cell_v2 discover_hosts --by-service
[root@bare ~]# systemctl enable openstack-nova-compute.service
[root@bare ~]# systemctl start openstack-nova-compute.service
[root@controller ~]# systemctl restart openstack-nova-scheduler

8.9 验证Bare Metal节点(控制节点)

[root@bare ~]# openstack compute service list
命令行展示

9 部署Ironic Network(控制节点、Bare Metal)

Ironic由以下三种网络组成:

  • Provisioning Network:用来注册并部署裸金属实例的网络,所以要求连通IPMI、DHCP、PXE以及裸金
    属服务器,有Flat、VLAN、SDN等多种方案,此次部署采用Flat网络
  • Cleaning Netowork:用于初始化裸金属节点,完成抹盘、初始化配置信息等工作。要求连通IPMI以及
    裸金属服务器
  • Tenant Netowork:常规的Neutron租户网络

9.1 部署Ovs Agent(Bare Metal)

这里已经有一个完善的OpenStack Neutron环境,所以只需配置Bare Metal节点即可。

[root@bare ~]# yum install openstack-neutron-openvswitch ipset -

9.2 配置Ovs Agent(Bare Metal)

[root@bare ~]# vi /etc/neutron/plugins/ml2/openvswitch_agent.ini
[agent]
l2_population = true
arp_responder = true
[ovs]
bridge_mappings = provider:br-provider
datapath_type = system
local_ip = 192.168.5.221
[securitygroup]
enable_security_group = True
firewall_driver = neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver

9.3 启动OpenvSwitch服务(Bare Metal)

[root@bare ~]# systemctl enable neutron-openvswitch-agent
[root@bare ~]# systemctl start neutron-openvswitch-agent

9.4 手动创建网桥绑定网卡(Bare Metal)

因为我们这里选择的是Flat网络模式,所以需要Ovs网桥和物理网卡绑定用来访问外网。

[root@bare ~]# ovs-vsctl add-br br-provider
[root@bare ~]# ovs-vsctl add-port br-provider ens192

9.5 验证Ovs网桥(Bare Metal)

[root@bare ironic]# ovs-vsctl show
7c01fc3a-3aca-4a08-bf0d-76d1b6703f87
    Manager "ptcp:6640:127.0.0.1"
        is_connected: true
    Bridge br-provider
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port "ens192"
            Interface "ens192"
        Port br-provider
            Interface br-provider
                type: internal
        Port phy-br-provider
            Interface phy-br-provider
                type: patch
                options: {peer=int-br-provider}
    Bridge br-int
        Controller "tcp:127.0.0.1:6633"
            is_connected: true
        fail_mode: secure
        Port int-br-provider
            Interface int-br-provider
                type: patch
                options: {peer=phy-br-provider}
        Port br-int
            Interface br-int
                type: internal
ovs_version: "2.11.0"

9.6 控制节点Neutron配置(控制节点)

控制节点Neutron是提前配置好的,这里检查一下配置文件。

[root@controller ~]# vi /etc/neutron/neutron.conf 
[DEFAULT]
state_path = /var/lib/neutron
auth_strategy = keystone
core_plugin = ml2
service_plugins = router
allow_overlapping_ips = True
notify_nova_on_port_status_changes = true
notify_nova_on_port_data_changes = true
transport_url = rabbit://openstack:tera123@192.168.5.220
[database]
connection = mysql+pymysql://neutron:tera123@192.168.5.220/neutron
[keystone_authtoken]
www_authenticate_uri = http://192.168.5.220:5000
auth_url = http://192.168.5.220:5000
memcached_servers = 192.168.5.220:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = neutron
password = tera123
[nova]
auth_url = http://192.168.5.220:5000
auth_type = password
project_domain_name = default
user_domain_name = default
region_name = RegionOne
project_name = service
username = nova
password = tera123

[root@controller ~]# vi /etc/neutron/plugins/ml2/ml2_conf.ini
[ml2]
type_drivers = flat,vlan,vxlan
tenant_network_types = vxlan,flat
mechanism_drivers = openvswitch,l2population,baremetal
extension_drivers = port_security
[ml2_type_vxlan]
vni_ranges = 1:1000
[ml2_type_flat]
flat_networks = provider
[securitygroup]
firewall_driver = neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver
enable_ipset = true
enable_security_group = true

[root@controller ~]# vi /etc/neutron/plugins/ml2/openvswitch_agent.ini
[agent]
tunnel_types = vxlan
l2_population = true
arp_responder = true
[ovs]
bridge_mappings = provider:br-provider
datapath_type = system
local_ip = 192.168.5.220
[securitygroup]
enable_security_group = True
firewall_driver = neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver

9.7 安装Ironic Neutron Agent(控制节点)

[root@controller ~]# yum install -y python2-ironic-neutron-agent
[root@controller ~]# vi /etc/neutron/plugins/ml2/ironic_neutron_agent.ini
[DEFAULT]
debug = true
[agent]
log_agent_heartbeats = true
[ironic]
project_domain_name = default
project_name = service
user_domain_name = default
password = tera123
username = ironic
auth_url = http://192.168.5.220:5000/v3
auth_type = password

9.8 启动Ironic Neutron Agent(控制节点)

[root@controller ~]# systemctl enable ironic-neutron-agent 
[root@controller ~]# systemctl start ironic-neutron-agent 

9.9 安装Baremetal插件(控制节点)

以往使用Flat网络接口时创建的裸机Port状态会一直处于DOWN,但裸机操作系统的部署依然能够成功且正常工作。而 Networking-baremetal项目正是希望解决裸机Port状态不正常的问题,该项目提供了网络服务和裸机服务深度集成的功能,不仅能完成裸机Port状态变更,还能提供Routed Networks功能。

[root@controller ~]# yum install python2-networking-baremetal -y
[root@controller ~]# systemctl restart neutron-server

9.10 创建Provisioning Network(控制节点)

创建一个 Flat 类型的 Provisioning Network,该网络通过虚拟二层直接与物理二层网络通信,通过物理交换机连通到裸金属服务器,使得裸金属服务器可以借助该网络DHCP服务获取到IP地址和PXE服务器的信息。所以Subnet一定要Enable DHCP。

[root@controller ~]# openstack network create --project admin flat --share --provider-network-type flat --provider-physical-network provider
[root@controller ~]# openstack subnet create subnet \
--network flat --subnet-range 192.168.4.0/24 --ip-version 4 \
--gateway 192.168.4.1 --allocation-pool start=192.168.4.230,end=192.168.4.240 --dhcp

9.11 Ironic使用Neutron Network(Bare Metal)

配置Ironic使用Cleaning Network和Provisioning Network。

[root@controller ~]# openstack network list
命令行展示
[root@controller ~]# openstack security group list
命令行展示
[root@bare ~]# vi /etc/ironic/ironic.conf
[neutron]
cleaning_network=3793d3bd-5a26-4dd2-a637-007b8ed7c2b0
cleaning_network_security_groups=42263b5f-cdff-4374-a04c-506cc22eee70
provisioning_network=3793d3bd-5a26-4dd2-a637-007b8ed7c2b0
provisioning_network_security_groups=42263b5f-cdff-4374-a04c-506cc22eee70
[root@bare ~]# systemctl restart openstack-ironic-conductor openstack-ironic-api 

10 构建镜像(控制节点)

Ironic镜像分为Deploy镜像和User镜像两种,Deploy镜像用来给裸机使用,来引导最终的OS,User镜像则是用户最终会使用到的镜像。

10.1 构建Deploy Images

这里我们没有定制镜像的需求,所以直接下载。

[root@controller ~]# wget \ 
https://tarballs.openstack.org/ironic-python-agent/coreos/files/coreos_production_pxe.vmlinuz
[root@controller ~]#wget \
https://tarballs.openstack.org/ironic-python-agent/coreos/files/coreos_production_pxe_image-oem.cpio.gz 

10.2 上传Deploy Images

[root@controller ~]# glance image-create --name deploy-vmlinuz --visibility public --disk-format aki --container-format aki < coreos_production_pxe.vmlinuz
[root@controller ~]# glance image-create --name deploy-initrd --visibility public --disk-format ari --container-format ari < coreos_production_pxe_image-oem.cpio.gz

10.3 构建User Images

这里要自定义用户名和密码,需要传递变量,注意镜像的用户不能为root。

[root@controller ~]# export DIB_CLOUD_INIT_DATASOURCES="ConfigDrive, OpenStack"
[root@controller ~]# export DIB_DEV_USER_USERNAME=centos
[root@controller ~]# export DIB_DEV_USER_PWDLESS_SUDO=yes 
[root@controller ~]# export DIB_DEV_USER_PASSWORD=tera123
[root@controller~]# disk-image-create my-initrd baremetal dhcp-all-interfaces grub2 install-static devuser -o centos7 cloud-init-datasources

10.4 上传User Images

[root@controller ~]# glance image-create --name my-image.vmlinuz --visibility public --disk-format aki --container-format aki < my-image.vmlinuz
[root@controller ~]# glance image-create --name my-image.initrd --visibility public --disk-format ari --container-format ari < my-image.initrd
[root@controller ~]# export MY_VMLINUZ_UUID=$(openstack image list | awk '/my-image.vmlinuz/ { print $2 }')
[root@controller ~]# export MY_INITRD_UUID=$(openstack image list | awk '/my-image.initrd/ { print $2 }')
[root@controller ~]# glance image-create --name my-image --visibility \
public --disk-format qcow2 --container-format bare --property \
kernel_id=$MY_VMLINUZ_UUID --property ramdisk_id=$MY_INITRD_UUID < my-image.qcow2

11 配置Bare Metal驱动(Bare Metal)

本次部署采用的是PEX+IPMI的驱动来支持,IPMI控制硬件设备,PXE实施部署。需要提前配置好裸机带外管理口IP地址。

11.1 修改Ironic配置文件

[root@bare ~]# vi /etc/ironic/ironic.conf
[DEFAULT]
my_ip=192.168.5.220
transport_url = rabbit://openstack:tera123@192.168.5.220
auth_strategy = keystone
enabled_hardware_types = ipmi
enabled_boot_interfaces = pxe
enabled_console_interfaces = ipmitool-socat,no-console
enabled_deploy_interfaces = iscsi
enabled_inspect_interfaces = inspector
enabled_management_interfaces = ipmitool
enabled_power_interfaces = ipmitool
enabled_raid_interfaces = agent
enabled_vendor_interfaces = ipmitool, no-vendor
enabled_storage_interfaces = cinder, noop
enabled_network_interfaces = flat,neutron

11.2 配置PXE服务器

[root@bare ~]# vi /etc/ironic/ironic.conf
[ipmi]
retry_timeout=60
[pxe]
ipxe_enabled = False
pxe_append_params=nofb nomodeset vga=normal console=ttyS0 systemd.journald.forward_to_console=Yes
tftp_root=/tftpboot
tftp_server=192.168.5.221

11.3 重启服务并验证

[root@bare ~]# systemctl restart openstack-ironic-conductor
[root@bare ~]# openstack baremetal driver list
命令行展示

11.4 安装IPMI Tool并验证

IPMI Tool要确保能够和目标主机带外管理口通信。

[root@bare ~]# yum -y install ipmitool 
[root@bare ~]# ipmitool -I lanplus -H 192.168.5.33 -U ADMIN -P tera123 chassis power status
Chassis Power is on

11.5 配置TFTP服务

[root@bare ~]# mkdir /tftpboot
[root@bare ~]# chown -R ironic.ironic /tftpboot
[root@bare ~]# yum -y install tftp-server syslinux-tftpboot xinetd 
[root@bare ~]# vi /etc/xinetd.d/tftp
service tftp
{
  protocol        = udp
  port            = 69
  socket_type     = dgram
  wait            = yes
  user            = root
  server          = /usr/sbin/in.tftpd
  server_args     = -v -v -v -v -v --map-file /tftpboot/map-file /tftpboot
  disable         = no
  flags           = IPv4
}
[root@bare ~]# cp /usr/share/syslinux/pxelinux.0 /tftpboot
[root@bare ~]# cp /usr/share/syslinux/chain.c32 /tftpboot
[root@bare ~]# echo 're ^(/tftpboot/) /tftpboot/\2' > /tftpboot/map-file 
echo 're ^/tftpboot/ /tftpboot/' >> /tftpboot/map-file 
echo 're ^(^/) /tftpboot/\1' >> /tftpboot/map-file 
echo 're ^([^/]) /tftpboot/\1' >> /tftpboot/map-file

11.6 启动TFTP并验证

[root@bare ~]# systemctl enable xinetd
[root@bare ~]# systemctl start xinetd
[root@bare ~]# echo 'tftp' > /tftpboot/1
[root@controller ~]# tftp 192.168.5.221 -c get 1
[root@controller ~]# cat 1
Tftp

11.7 安装ISCSI Deploy支持工具

因为使用 iSCSI Deploy 方式的话,Ironic Conductor 节点会作为 iSCSI Client 并执行镜像的注入,所以需要安装 qemu-img 和 iscsiadm 指令行工具。

[root@bare ~]# yum -y install qemu-img iscsi-initiator-utils

12 注册裸机(控制节点)

12.1 创建Ironic Node

创建一个执行 IPMI 的 Ironic Node。

[root@controller ~]# export IRONIC_API_VERSION=1.11
[root@controller ~]# export OS_BAREMETAL_API_VERSION=1.11
[root@controller ~]# openstack baremetal node create --driver ipmi --name node1

12.2 设备部署接口类型

设置部署接口类型,现在可支持ISCSI、Direct、Ansible等类型,每种类型都有不同的行为模型,可根据实际情况选择,这里我们选择最简单的、但却在生产环境中并不特别友好(占用 Provisioning Network 的带宽)的 ISCSI类型。

[root@controller ~]# openstack baremetal node list
命令行展示
[root@controller ~]# openstack baremetal --os-baremetal-api-version 1.31 \
node set c83162c6-748f-4c90-840b-d5e07df83c97  \ 
--deploy-interface iscsi      --raid-interface agent

12.3 设置IPMI Info

这里主要配置IPMI的登录账户信息。

[root@controller ~]# openstack baremetal node set c83162c6-748f-4c90-840b-d5e07df83c97 \
                   --driver-info ipmi_username=ADMIN \
                   --driver-info ipmi_password=tera123 \
                   --driver-info ipmi_address=192.168.5.33

12.4 设置Deploy Images

通过RAMDisk的方式启动。

[root@controller ~]# openstack baremetal node set c83162c6-748f-4c90-840b-d5e07df83c97 \
                   --driver-info deploy_kernel=fcce4694-3955-40c8-be2f-c5ba890071ec \
                   --driver-info deploy_ramdisk= 0fbd622c-bb9e-4729-8cab-f2aae07a5814

12.5 设置Provisioning/Cleaning Network

[root@controller ~]# openstack baremetal node set c83162c6-748f-4c90-840b-d5e07df83c97 \
                   --driver-info cleaning_network= 3793d3bd-5a26-4dd2-a637-007b8ed7c2b0 \
--driver-info provisioning_network= 3793d3bd-5a26-4dd2-a637-007b8ed7c2b0

12.6 设置PXE网卡MAC地址

在Provisioning网络中通过这个MAC地址为Node分配IP地址。

[root@controller ~]# openstack baremetal port create ac:1f:6b:da:d9:c0 \
 --node c83162c6-748f-4c90-840b-d5e07df83c97

12.7 配置Resource Class

为Ironic node设置Placement筛选候选人的Resource Class类型,Nova-compute for Ironic会自动为其创建Placement Resource Provider。

[root@controller ~]# openstack --os-baremetal-api-version 1.21 baremetal node set c83162c6-748f-4c90-840b-d5e07df83c97 --resource-class BAREMETAL_TEST

12.8 设置Ironic Node基础信息

[root@controller ~]# openstack baremetal node set c83162c6-748f-4c90-840b-d5e07df83c97 \
--property cpus=48 --property memory_mb=131072 --property local_gb=1000
[root@controller ~]# openstack baremetal node set c83162c6-748f-4c90-840b-d5e07df83c97 \
--property capabilities='boot_mode:bios'

12.9 验证Ironic Node纳管

[root@controller ~]# openstack baremetal --os-baremetal-api-version 1.11 node manage c83162c6-748f-4c90-840b-d5e07df83c97
[root@controller ~]# openstack baremetal --os-baremetal-api-version 1.11 node provide c83162c6-748f-4c90-840b-d5e07df83c97
[root@controller ~]# openstack baremetal node show c83162c6-748f-4c90-840b-d5e07df83c97\
| grep provision_state
| provision_state        | available

12.10 创建实例Flavor

[root@controller ~]# openstack flavor create --ram 131072 --vcpus 48 --disk 100 my-baremetal-flavor
[root@controller ~]# openstack flavor set --property resources:CUSTOM_BAREMETAL_TEST=1 my-
baremetal-flavor
[root@controller ~]# openstack flavor set --property resources:VCPU=0 my-baremetal-flavor 
[root@controller ~]# openstack flavor set --property resources:MEMORY_MB=0 my-baremetal-flavor 
[root@controller ~]# openstack flavor set --property resources:DISK_GB=0 my-baremetal-flavor

13 实例部署(控制节点)

13.1 执行部署

[root@controller ~]# openstack server create --flavor my-baremetal-flavor \ 
--nic net-id=3793d3bd-5a26-4dd2-a637-007b8ed7c2b0 \
--image 08e111be-d256-4c43-bb07-ea65a1219f77 test

13.2 验证结果

[root@controller ~]# openstack server list
命令行展示
[root@controller ~]# openstack baremetal port show eb97e31d-5200-4f1a-beef-75a1c91cc1b6
命令行展示
[root@controller ~]# openstack port show baed8d7c-b6fc-48e8-8cc8-b16b7b55d4a2
命令行展示
[root@controller ~]# ssh root@192.168.4.236
命令行展示

14 常见问题

14.1 获取swift_temp_url报错

MissingAuthPlugin: An auth plugin is required to determine endpoint URL。因为我们选择了Direct的部署方式,裸机服务器的IPA会从Swift Object Storage将User Image拉到本地,在裸机端完成镜像注入,但是我们环境中没有部署Swift,所以需要改为ISCSI的部署方式。

[root@controller ~]# openstack baremetal --os-baremetal-api-version 1.31\
 node set c83162c6-748f-4c90-840b-d5e07df83c97 \
 --deploy-interface iscsi   --raid-interface agent

14.2 DHCP报错

PXE-E51: No DHCP or proxyDHCP offers were received。这是在为裸机MAC地址分配IP地址时发生的报错,主要原因是因为DHCP服务器与裸机网络不通,需要确保DHCP服务器与裸机之间可以通信。检查Neutron的配合文件,测试Provisioning网络的可用性。

14.3 TFTP Time out

PXE-E32 TFTP open timeout。

TFTP…这是在裸机分配到IP地址之后,下载Deploy Images时发生的报错,因为已经分配到IP地址,所以provisioning网络是没有问题的,发生这个报错可能是因为TFTP服务没有启动或者是TFTP服务器和裸机两者之间路由不通,本次部署是因为路由不通导致的TFTP超时。

14.4 Unexpected error while running commad

dd: error writing '/dev/disk/by-path/ip-192.168.4.234:3260-iscsi-iqn.2008-10.org.openstack:c83162c6-748f-4c95e07df83c97-lun-1-part1': InstanceDeployFailure: Deploy failed for instance 7837119e-a626-45d9-8233-21ebcb19aa28. Error: Unexpected error while running command.

这个报错发生在Deploy的最后一步注入用户镜像,起初以为是裸机硬盘损坏无法注入完整镜像,通过更换物理硬盘没有解决问题。后来发现在注入用户镜像的过程中会发生Bare Metal节点和裸机之间网络不通的问题,因为给裸机注入镜像是通过ISCSI方式连接3260端口挂载裸机硬盘到本地注入,网络不通直接就会导致挂载硬盘失败。此时观察裸机网络发现居然有两个IP,一个是通过部署的DHCP分配的4网段IP也就是我们Provisioning网络的IP与Bare Metal不通,第二个网段IP是其他DHCP分配,但是和Bare Metal之间可以互通,猜测可能是因为两个IP导致4段IP不是主路由IP。拔掉5网段网线,再次部署,注入镜像成功。

14.5 Ping不通裸机

裸机部署完成之后,PING/SSH裸机失败。是因为没有指定安全组,默认安全组没有放行。

[root@bare ~]# vi /etc/ironic/ironic.conf
[neutron]
cleaning_network=3793d3bd-5a26-4dd2-a637-007b8ed7c2b0
cleaning_network_security_groups=42263b5f-cdff-4374-a04c-506cc22eee70
provisioning_network=3793d3bd-5a26-4dd2-a637-007b8ed7c2b0
provisioning_network_security_groups=42263b5f-cdff-4374-a04c-506cc22eee70

14.6 获取Deploy Image报错

ERROR while preparing to deploy to node : MissingAuthPlugin: An auth plugin is required to determine endpoint URL,这是一个Bug。获取Image的时候MissingAuthPlugin是因为没有配置Glance。

[root@bare ~]# vi /etc/ironic/ironic.conf
[glance]
url = http://192.168.5.220:9292
auth_url = http://192.168.5.220:5000
auth_type = password
project_domain_name = default
user_domain_name = default	
region_name = RegionOne
project_name = service
username = glance
password = tera123

15 参考文献

OpenStack官网:https://docs.openstack.org/

6 参考资料

如有其它问题,请填写右侧需求表单联系我们。www.asterfusion.com

配置指导:OpenStack-OpenvSwitch 安装部署

1 OpenStack简介

OpenStack是一个由NASA(美国国家航空航天局)和Rackspace合作研发并发起的,以Apache许可证授权的自由软件和开放源代码项目。OpenStack支持几乎所有类型的云环境,项目目标是提供实施简单、可大规模扩展、丰富、标准统一的云计算管理平台。OpenStack通过各种互补的服务提供了基础设施即服务(IaaS)的解决方案,每个服务提供API以进行集成。

2 OpenStack架构图

整个OpenStack是由控制节点,计算节点,网络节点,存储节点四大部分组成。控制节点负责对其余节点的控制,包含虚拟机建立,迁移,网络分配,存储分配等等。计算节点负责虚拟机运行网络节点负责对外网络与内网络之间的通信存储节点负责对虚拟机的额外存储管理。其中各组件架构图如下:

OpenStack架构图

3 OpenStack必要组件

  • 认证管理服务,提供了Openstack其余所有组件的认证信息/令牌的管理、创建、修改等等,使用MySQL等数据库存储认证信息
  • 计算管理服务,是Openstack计算的弹性控制,提供虚拟机的创建、运行、迁移、快照等围绕虚拟机的服务,并提供API与控制节点对接,由控制节点下发任务,使用nova-api进行通信
  • 网络管理服务,提供了对网络节点的网络拓扑管理,负责管理私有网络与公有网络的通信,以及管理虚拟机网络之间通信/拓扑、管理虚拟机之上的防火墙等,同时提供Neutron在Horizon的管理界面
  • 镜像管理服务,用于管理虚拟机部署时所能提供的镜像,包含镜像的导入、格式以及制作相应的模板,是一套虚拟机镜像发现、注册、检索系统,所有计算实例都是从Glance镜像启动的
  • 控制台服务,是一个用以管理、控制Openstack服务的Web控制面板,它可以管理实例、镜像、创建密匙对,对实例添加卷、操作Swift容器等,用户还可以在控制面板中使用终端(console)或VNC直接访问实例

4 OpenStack基础服务

  • OpenStack使用SQL数据库来存储信息。该数据库通常在控制器节点上运行
  • OpenStack使用消息队列来协调服务之间的操作和状态信息。消息队列服务通常在控制器节点上运行
  • 服务的身份服务、身份验证机制使用Memcached来缓存令牌。Memcached服务通常在控制器节点上运行
  • OpenStack服务使用Etcd(分布式可靠的键值存储)进行分布式键锁定,存储配置,跟踪服务活动性和其他情况

5 硬件配置

主机系统网卡1:eno1网卡2:eno2
openstackCentos7.6192.168.4.145192.168.5.145
computeCentos7.6192.168.4.144192.168.5.144

服务器具体配置要求如下:

  • 2个千兆网口
  • 至少8G内存
  • 磁盘至少40G
  • 计算节点的BISO中开启CPU嵌套虚拟化(INTEL叫VT-x,AMD的叫AMD-V)

6 系统优化

主机的优化不单纯只是软硬件的优化,基于操作系统的性能优化也是多方面的,可以从几个方面进行衡量,以更好的提高主机的性能。

6.1 关闭SELinux(控制节点、计算节点)

SELinux不关闭的情况下无法实现,会限制ssh免密码登录。

[root@localhost  ~]# setenforce 0 
[root@localhost  ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux

6.2 关闭防火墙(控制节点、计算节点)

防止安装时出现各个组件的端口不能访问的问题。

[root@localhost  ~]#systemctl stop firewalld && systemctl disable firewalld                          

6.3 时间同步(控制节点、计算节点)

同步时间可以有效解决因时间不同而造成的不同步。

[root@localshot  ~]# yum -y install ntp
[root@localhost  ~]# ntpdate ntp1.aliyun.com
[root@localhost  ~]# timedatectl set-timezone Asia/Shanghai

6.4 内核隔离(控制节点、计算节点)

OpenStack部分机器用于做控制节点,大部分机器都是需要运行虚拟化软件,虚拟化平台有大量VM,而宿主机本身的系统也会跑一些服务,那么这就势必会造成VM与宿主机系统之间资源的抢占。我们可以通过修改内核参数指定操作系统使用指定的几个核,解决抢占问题。

[root@localhost  ~]# vi /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="isolcpus=8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47"
[root@localhost  ~]# update-grub

6.5 关闭KVM内存共享(计算节点)

内存配置方面,关闭KVM内存共享,打开透明大页,提升主机CPU性能。

[root@localhost  ~]# echo 0>/sys/kernel/mm/ksm/pages_shared
echo 0>/sys/kernel/mm/ksm/pages_sharing
echo always > /sys/kernel/mm/transparent_hugepage/enabled
echo always>/sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
[root@localhost  ~]# echo 0>/sys/kernel/mm/ksm/pages_shared
echo 0>/sys/kernel/mm/ksm/pages_sharing
echo always > /sys/kernel/mm/transparent_hugepage/enabled
echo always>/sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
echo 0 > /sys/kernel/mm/transparent_hugepage/khugepaged/defrag

6.6 修改系统打开文件最大数量(计算节点、控制节点)

放开系统打开文件最大数量,防止因达到上限值而导致的进程终止。

[root@localhost  ~]# vi /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535

6.7 降低Swap分区使用率(控制节点、计算节点) 

现在服务器的内存一般是上百GB,所以我们可以把这个参数值设置的低一些(如10-30之间),让操作系统尽可能的使用物理内存,降低系统对swap的使用,从而提高宿主机系统和虚拟机的性能。

[root@localhost  ~]# echo 'vm.swappiness=10' >>/etc/sysctl.conf

7 基础服务部署

7.1 安装OpenStack国内yum源(控制节点、计算节点)

安装阿里的OpenStack yum源可以加快各组件的下载速度。

[root@localhost  ~]# cat << EOF >> /etc/yum.repos.d/openstack.repo
[openstack-rocky]
name=openstack-rocky
baseurl=https://mirrors.aliyun.com/centos/7/cloud/x86_64/openstack-rocky/
enabled=1
gpgcheck=0
[qume-kvm]
name=qemu-kvm
baseurl= https://mirrors.aliyun.com/centos/7/virt/x86_64/kvm-common/
enabled=1
gpgcheck=0
EOF

7.2 部署OpenStackClient(控制节点)

[root@localhost  ~]# yum upgrade -y
[root@localhost  ~]# yum install -y python-openstackclient openstack-selinux

7.3 部署MySQL(控制节点)

部署MySQL并且通过修改配置文件更改存储路径。

[root@localhost  ~]# yum install -y mariadb mariadb-server python2-PyMySQL
[root@localhost  ~]# vi /etc/my.cnf.d/openstack.cnf
[mysqld]
bind-address=192.168.4.145
default-storage-engine = innodb
innodb_file_per_table = on
max_connections = 4096
collation-server = utf8_general_ci
character-set-server = utf8
[root@localhost  ~]# vi /etc/my.cnf
[client-mariadb]
socket=/var/lib/mysql/mysql.sock
[mysqld]
query_cache_size = 0
query_cache_type = OFF
max_connections = 4096
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid

7.4 启动MySQL(控制节点)、

修改MySQL用户密码,并且system管理MySQL。

[root@localhost  ~]# systemctl enable mariadb
[root@localhost  ~]# systemctl start mariadb
[root@localhost  ~]# mysql -uroot 
MariaDB [(none)]> update mysql.user set password=password('tera123') where user = 'root';
MariaDB [(none)]> flush privileges;

7.5 部署RabbitMq(控制节点)

部署RabbitMq来协调服务之间的操作和状态信息,并且修改RabbitMq存储路径。

[root@localhost  ~]# yum -y install rabbitmq-server
[root@localhost  ~]# vi /etc/rabbitmq/rabbitmq-env.conf
RABBITMQ_MNESIA_BASE=/var/lib/rabbitmq/mnesia
RABBITMQ_LOG_BASE=/var/lib/rabbitmq/log
[root@localhost  ~]# mkdir -p /var/lib/rabbitmq/mnesia
[root@localhost  ~]# mkdir -p /var/lib/rabbitmq/log
[root@localhost  ~]# chmod -R 755 /var/lib/rabbitmq
[root@localhost  ~]# systemctl enable rabbitmq-server.service
[root@localhost  ~]# systemctl start rabbitmq-server.service

7.6 配置RabbitMq用户 (控制节点)

添加OpenStack用户并且配置用户权限

[root@localhost  ~]# rabbitmqctl add_user openstack tera123
Creating user “openstack” …
[root@localhost  ~]# rabbitmqctl set_permissions openstack ".*" ".*" ".*"
Setting permissions for user “openstack” in vhost “/”…

7.7 部署Memcached(控制节点)

部署Memcached,并修改配置文件。

[root@localhost  ~]# yum -y install memcached
[root@localhost  ~]# vi /etc/sysconfig/memcached
OPTIONS="-l 127.0.0.1,::1,192.168.4.145"
[root@localhost  ~]# systemctl enable memcached
[root@localhost  ~]# systemctl start memcached

7.8 部署Etcd(控制节点)

部署Etcd,修改配置文件,并且使用system管理。

[root@localhost  ~]# yum -y install etcd
[root@localhost  ~]# vi /etc/etcd/etcd.conf
ETCD_LISTEN_PEER_URLS=http://192.168.4.145:2380
ETCD_LISTEN_CLIENT_URLS="http://192.168.4.145:2379,http://127.0.0.1:2379"
ETCD_NAME="controller"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.4.145:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.4.145:2379"
ETCD_INITIAL_CLUSTER="controller=http://192.168.4.145:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
[root@localhost  ~]# systemctl enable etcd
[root@localhost  ~]# systemctl start etcd

8 Keystone(控制节点)

OpenStack Identity服务提供了一个集成点,用于管理身份验证,授权和服务目录。

Keystone通常是用户与之交互的第一项服务。身份验证后,最终用户可以使用其身份访问其他OpenStack服务。同样,其他OpenStack服务利用Keystone来确保用户是他们所说的人,并发现其他服务在部署中的位置用户和服务可以使用由Keystone管理的服务目录来查找其他服务。

服务目录是OpenStack部署中可用服务的集合。每个服务可以具有一个或多个端点,并且每个端点可以是以下三种类型之一:admin,internal或public。在生产环境中,出于安全原因,不同的终结点类型可能驻留在暴露给不同类型用户的单独网络上。

8.1 MySQL中创建库和权限

在数据库中创建Keystone用户,并且授予用户访问库的权限。

[root@localhost  ~]# mysql -uroot -p
MariaDB [(none)]> create database keystone;
MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' identified by 'tera123';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' identified by 'tera123';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'openstack' identified by 'tera123';

8.2 安装Keystone组件服务

部署openstack-keystone、http、http模块,配置Keystone。

[root@localhost  ~]# yum install openstack-keystone httpd mod_wsgi
[root@localhost  ~]# vi /etc/keystone/keystone.conf
[database]
connection=mysql+pymysql://keystone:tera123@192.168.4.145/keystone
[token]
provider=fernet

8.3 配置keystone库

导入keytone库SQL,初始化Fernet秘钥库存储,引导身份服务。

[root@localhost  ~]# su -s /bin/sh -c "keystone-manage db_sync" keystone
[root@localhost ~]# keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone
[root@localhost~]# keystone-manage credential_setup --keystone-user keystone --keystone-group keystone
[root@localhost  ~]# keystone-manage bootstrap --bootstrap-password tera123\ 
--bootstrap-admin-url http://192.168.4.145:5000/v3/ \
--bootstrap-internal-url http://192.168.4.145:5000/v3/ \
--bootstrap-public-url http://192.168.4.145:5000/v3/ \
--bootstrap-region-id RegionOne

8.4 配置Apache HTTP服务器

[root@localhost  ~]# vi /etc/httpd/conf/httpd.conf
ServerName 192.168.4.145
[root@localhost  ~]# ln -s /usr/share/keystone/wsgi-keystone.conf  /etc/httpd/conf.d/

8.5 完成部署

System管理Keystone并且配置管理账户。

[root@localhost  ~]# systemctl enable httpd.service
[root@localhost  ~]# systemctl start httpd.service
[root@localhost  ~]# vi admin-openrc
export OS_USERNAME=admin
export OS_PASSWORD=tera123
export OS_PROJECT_NAME=admin
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_DOMAIN_NAME=Default
export OS_AUTH_URL=http://192.168.4.145:5000/v3
export OS_IDENTITY_API_VERSION=3

8.6 创建Service项目

[root@localhost  ~]# openstack project create --domain default \
                    --description "Service Project" service
[root@localhost  ~]# openstack role create user

8.7 验证Keystone

[root@localhost  ~]# openstack user list
+----------------------------------------------------------------+--------------+
| ID                                  | Name  |
| 57341d3e37eb4dc997624f9502495e44 | admin  |
+-----------------------------------------------------------------+--------------+

9 Glance(控制节点)

Glance使用户可以发现、注册和检索虚拟机镜像。它提供了 REST API,使您可以查询虚拟机镜像元数据并检索实际镜像。您可以将通过Image服务提供的虚拟机存储在从简单文件系统到对象存储系统(如OpenStack Object Storage)的各种位置。Glance由以下部分组成:

  • glance-api:用于接收Glance发现、检索和存储的Image API调用
  • glance-registry:存储、处理和检索有关Glance的元数据。元数据包括大小和类型等项目

9.1 MySQL中创建库和权限

在数据库中创建Glance用户,并且授予用户访问库的权限。

[root@localhost  ~]# mysql -uroot -p
MariaDB [(none)]> create database glance;
MariaDB [(none)]>GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost' identified by 'tera123';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'%' identified by 'tera123';
MariaDB [(none)]>GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'openstack' identified by 'tera123';

9.2 创建用户、服务

创建Glance用户,并且给Glance授权Admin role,创建服务向Keystone暴露Endpoint。

[root@localhost  ~]# openstack user create --domain default --password-prompt glance
[root@localhost  ~]# openstack role add --project service --user glance admin
[root@localhost  ~]# openstack service create --name glance \
 --description "OpenStack Image" image
[root@localhost  ~]# openstack endpoint create --region RegionOne image public \
                    http://192.168.4.145:9292
[root@localhost  ~]# openstack endpoint create --region RegionOne image internal \
                    http://192.168.4.145:9292
[root@localhost  ~]# openstack endpoint create --region RegionOne image admin \
                    http://192.168.4.145:9292


9.3 安装Glance组件服务

安装软件包,编辑Glance配置文件。

[root@localhost  ~]# yum install -y openstack-glance
[root@localhost  ~]# vi /etc/glance/glance-api.conf
[database]
connection = mysql+pymysql://glance:tera123@192.168.4.145/glance
[glance_store]
stores = file,http
default_store = file
[keystone_authtoken]
www_authenticate_uri = http://192.168.4.145:5000
auth_url = http://192.168.4.145:5000
memcached_servers = 192.168.4.145:11211
auth_type = password
project_domain_name = Default
user_domain_name = Default
project_name = service
username = glance
password = 123456
[paste_deploy]
flavor = keystone
[root@loaclhost  ~]# vi /etc/glance/glance-registry.conf
[database]
connection = mysql+pymysql://glance:tera123@192.168.4.145/glance
[keystone_authtoken]
www_authenticate_uri = http://192.168.4.145:5000
auth_url = http://192.168.4.145:5000
memcached_servers = 192.168.4.145:11211
auth_type = password
project_domain_name = Default
user_domain_name = Default
project_name = service
username = glance
password = 123456
[paste_deploy]
flavor = keystone

9.4 同步数据库

导入Glance库的SQL文件,启动Glance服务。

[root@localhost  ~]# su -s /bin/sh -c "glance-manage db_sync" glance
[root@localhost  ~]# systemctl start openstack-glance-api openstack-glance-registry
[root@localhost  ~]# systemctl enable openstack-glance-api openstack-glance-registry

9.5 验证Glance服务

上传镜像验证Glance服务可用性。

[root@localhost  ~]# wget http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img
[root@localhost  ~]# openstack image create "cirros" --file cirros-0.3.4-x86_64-disk.img --disk-format qcow2 --container-format bare --public
[root@localhost  ~]# openstack image list
+------------------------------------------------------------------+----------------------------+------------+
| ID                                   | Name          | Status  |
+------------------------------------------------------------------+----------------------------+------------+
| 6a1ba286-5ef2-409f-af11-5135e21adb4d | cirros          | active  |
+------------------------------------------------------------------+----------------------------+-------------+

10 Nova(控制节点)

使用OpenStack Compute托管和管理云计算系统。OpenStack Compute是基础架构即服务(IaaS)系统的主要部分。主要模块是用Python实现的。Nova由以下部分组成:

  • nova-api:接收并响应最终用户的compute调用。该服务支持OpenStack Compute API。它执行一些策略并启动大多数编排活动,例如运行实例
  • nova-api-metadata:接收来自实例的元数据请求
  • nova-compute:通过守护程序API创建和终止虚拟机实例的辅助程序守护程序
  • nova-placement-api:跟踪每个提供商的库存和使用情况
  • nova-scheduler:从队列中获取虚拟机实例请求,并通过计算确定它在哪台服务器主机上运行
  • nova-conductor:中介nova-compute服务与数据库之间的交互。消除了对数据库的直接访问
  • nova-consoleauth:为控制台代理提供的用户授权令牌
  • nova-novncproxy:提供用于通过VNC连接访问正在运行的实例的代理

10.1 MySQL中创建库和权限

在数据库中创建Nova用户,并且授予用户访问库的权限。

[root@localhost  ~]# mysql -uroot -p
MariaDB [(none)]> create database nova_api;
MariaDB [(none)]> create database nova;
MariaDB [(none)]> create database nova_cell0;
MariaDB [(none)]> create database placement;
MariaDB[(none)]>GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'localhost' identified by 'tera123';
MariaDB[(none)]>GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'%' identified by 'tera123';
MariaDB[(none)]>GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'openstack' identified by 'tera123';

MariaDB[(none)]>GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'localhost' identified by 'tera123'; 
MariaDB[(none)]>GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'%' identified by 'tera123';
MariaDB[(none)]>GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'openstack' identified by 'tera123';

MariaDB[(none)]>GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'localhost' identified by 'tera123';
MariaDB[(none)]>GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'%' identified by 'tera123';
MariaDB[(none)]>GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'openstack' identified by 'tera123';

MariaDB[(none)]>GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'localhost' identified by 'tera123';
MariaDB[(none)]>GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'%' identified by 'tera123';
MariaDB[(none)]>GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'openstack' identified by 'tera123';

10.2 创建Nova用户、服务

创建Nova用户,并且给Glance授权Admin role,创建服务向Keystone暴露Endpoint。

[root@localhost  ~]# openstack user create --domain default --password-prompt nova
[root@localhost  ~]# openstack role add --project service --user nova admin
[root@localhost  ~]# openstack service create --name nova \
--description "OpenStack compute" compute
[root@localhost  ~]# openstack endpoint create --region RegionOne compute public \
                    http://192.168.4.145:8774/v2.1
[root@localhost  ~]# openstack endpoint create --region RegionOne compute internal \
                    http://192.168.4.145:8774/v2.1
[root@localhost  ~]# openstack endpoint create --region RegionOne compute admin \
                    http://192.168.4.145:8774/v2.1

10.3 创建Placement用户、服务

创建Placement用户,并给Placement授权Admin role,创建服务向Keystone暴露Endpoint。

[root@localhost  ~]# openstack user create --domain default --password-prompt placement
[root@localhost  ~]# openstack role add --project service --user placement admin
[root@localhost  ~]# openstack service create --name placement \
 –description "Placement API" placement
[root@localhost  ~]# openstack endpoint create --region RegionOne placement public \
                    http://192.168.4.145:8778
[root@localhost  ~]# openstack endpoint create --region RegionOne placement internal \
                    http://192.168.4.145:8778
[root@localhost  ~]# openstack endpoint create --region RegionOne placement admin \
                    http://192.168.4.145:8778

10.4 安装Nova组件服务

安装Nova组件并且编辑配置文件。

[root@localhost  ~]# yum install openstack-nova-api openstack-nova-conductor \
openstack-nova-console openstack-nova-novncproxy \
openstack-nova-scheduler openstack-nova-placement-api -y
[root@localhost  ~]# vi /etc/nova/nova.conf
[DEFAULT]
my_ip=192.168.4.145
use_neutron=true
firewall_driver=nova.virt.firewall.NoopFirewallDriver
enabled_apis=osapi_compute,metadata
transport_url=rabbit://openstack:tera123@192.168.4.145
[api]
auth_strategy=keystone
[api_database]
connection=mysql+pymysql://nova:tera123@192.168.4.145/nova_api
[database]
connection= mysql+pymysql://nova:tera123@192.168.4.145/nova
[glance]
api_servers= http://192.168.4.145:9292
[keystone_authtoken]
www_authenticate_uri = http://192.168.4.145:5000
auth_url=http://192.168.4.145:5000/v3
memcached_servers= 192.168.4.145:11211
auth_type=password
project_domain_name = Default
user_domain_name = Default
project_name = service
username = nova
password = 123456
[placement]
region_name = RegionOne
user_domain_name = Default
auth_type=password
auth_url=http://192.168.4.145:5000/v3
project_name=service
project_domain_name=Default
username=placement
password=123456
[placement_database]
connection= mysql+pymysql://placement:tera123@192.168.4.145/placement
[scheduler]
discover_hosts_in_cells_interval= 300
[vnc]
enabled=true
server_listen=$my_ip
server_proxyclient_address=$my_ip

10.5 配置Placement API

通过将以下配置添加到来启用对Placement API的访问。 

[root@localhost  ~]# vi /etc/httpd/conf.d/00-nova-placement-api.conf
Listen 8778
<VirtualHost *:8778>
  <Directory /usr/bin>
   <IfVersion >= 2.4>
      Require all granted
   </IfVersion>
   <IfVersion < 2.4>
      Order allow,deny
      Allow from all
   </IfVersion>
 </Directory>
  WSGIProcessGroup nova-placement-api
  WSGIApplicationGroup %{GLOBAL}
  WSGIPassAuthorization On
  WSGIDaemonProcess nova-placement-api processes=3 threads=1 user=nova group=nova
  WSGIScriptAlias / /usr/bin/nova-placement-api
  <IfVersion >= 2.4>
    ErrorLogFormat "%M"
  </IfVersion>
  ErrorLog /var/log/nova/nova-placement-api.log
  #SSLEngine On
  #SSLCertificateFile ...
  #SSLCertificateKeyFile ...
</VirtualHost>
Alias /nova-placement-api /usr/bin/nova-placement-api
<Location /nova-placement-api>
  SetHandler wsgi-script
  Options +ExecCGI
  WSGIProcessGroup nova-placement-api
  WSGIApplicationGroup %{GLOBAL}
  WSGIPassAuthorization On
</Location>

10.6 同步数据库

导入nova-api、nova、cell0、placement库SQL。

[root@localhost  ~]# su -s /bin/sh -c "nova-manage api_db sync" nova
[root@localhost  ~]# su -s /bin/sh -c "nova-manage cell_v2 map_cell0" nova
[root@localhost  ~]# su -s /bin/sh -c "nova-manage cell_v2 create_cell --name=cell1 --verbose" nova  
[root@localhost  ~]# su -s /bin/sh -c "nova-manage db sync" nova 

10.7 验证Nova服务 

验证nova cell0和cell1是否正确注册,并启动Nova服务。

[root@openstack ~]# su -s /bin/sh -c "nova-manage cell_v2 list_cells" nova
+-------+--------------------------------------+---------------------------------------+----------------------------------------------------+----------+
|  Name |                 UUID                 |             Transport URL             |                Database Connection                 | Disabled |
+-------+--------------------------------------+---------------------------------------+----------------------------------------------------+----------+
| cell0 | 00000000-0000-0000-0000-000000000000 |                 none:/                | mysql+pymysql://nova:****@192.168.4.145/nova_cell0 |  False   |
| cell1 | 510ecc1a-4112-4832-b5a5-4f6d4581c545 | rabbit://openstack:****@192.168.4.145 |    mysql+pymysql://nova:****@192.168.4.145/nova    |  False   |
+-------+--------------------------------------+---------------------------------------+----------------------------------------------------+----------+
[root@localhost  ~]# systemctl enable openstack-nova-api.service   \
openstack-nova-consoleauth openstack-nova-scheduler.service \
                    openstack-nova-conductor.service openstack-nova-novncproxy.service
[root@localhost  ~]# systemctl start openstack-nova-api.service \
  openstack-nova-consoleauth   openstack-nova-scheduler.service\
  openstack-nova-conductor.service openstack-nova-novncproxy.service

11 Nova(计算节点)

11.1 安装Nova组件服务

安装Nova组件并且编辑配置文件。

[root@localhost  ~]# yum install openstack-nova-compute -y
[root@localhost  ~]# vi /etc/nova/nova.conf
[DEFAULT]
my_ip=192.168.4.144
use_neutron=true
firewall_driver=nova.virt.firewall.NoopFirewallDriver
enabled_apis=osapi_compute,metadata
transport_url=rabbit://openstack:tera123@192.168.4.145
[api]
auth_strategy=keystone
[glance]
api_servers=http://192.168.4.145:9292
[keystone_authtoken]
www_authenticate_uri = http://192.168.4.145:5000
auth_url=http://192.168.4.145:5000/v3
memcached_servers=192.168.4.145:11211
auth_type=password
project_domain_name = Default
user_domain_name = Default
project_name = service
username = nova
password = 123456
[placement]
region_name = RegionOne
project_domain_name = Default
project_name = service
auth_type = password
user_domain_name = Default
auth_url = http://192.168.4.145:5000/v3
username = placement
password = 123456
[vnc]
enabled=true
server_listen=0.0.0.0
server_proxyclient_address=$my_ip
novncproxy_base_url=http://192.168.4.145:6080/vnc_auto.html

11.2 检测是否支持虚拟化

如果不支持虚拟化,则要配置新的参数。

[root@localhost  ~]# egrep -c ‘(vmx|svm)’ /proc/cpuinfo
[root@localshot  ~]# vi /etc/nova/nova.conf
[libvirt]
virt_type = qemu

11.3 启动Nova服务

System管理Nova。

[root@localhost  ~]# systemctl enable libvirtd openstack-nova-compute
[root@localshot  ~]# systemctl start libvirtd openstack-nova-compute

11.4 发现计算节点(控制节点)

在控制节点确认计算节点。

[root@localhost  ~]# openstack compute service list --service nova-compute
[root@localshot  ~]# su -s /bin/sh -c "nova-manage cell_v2 discover_hosts --verbose" nova
Found 2 cell mappings.
Skipping cell0 since it does not contain hosts.
Getting computes from cell 'cell1': 54e6c270-7390-4390-8702-02b72874c5a7
Checking host mapping for compute host 'compute': 39d80423-6001-4036-a546-5287c1e93ec5
Creating host mapping for compute host 'compute': 39d80423-6001-4036-a546-5287c1e93ec5
Found 1 unmapped computes in cell: 54e6c270-7390-4390-8702-02b72874c5a7

12 Neutron(控制节点)

OpenStack Networking(neutron)允许创建由其他OpenStack服务管理的接口设备并将其连接到网络。可以实施插件来容纳不同的网络设备和软件,从而为OpenStack体系结构和部署提供灵活性。它包括以下组件:

  • neutron-server:接收API服务器请求并将其路由到适合的OpenStack网络设备以采取措施
  • OpenStack Networking plug-ins and agents:OpenStack通用代理是L3,DHCP和插件代理

12.1 MySQL中创建库和权限

在数据库中创建Neutron用户,并且授予用户访问库的权限。

[root@localhost  ~]# mysql -uroot -p
MariaDB [(none)]> create database neutron;
MariaDB[(none)]>GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost' identified by 'tera123';
MariaDB[(none)]>GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%' identified by 'tera123';
MariaDB[(none)]>GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'openstack' identified by 'tera123'; 

12.2 创建Neutron用户、服务

创建Neutron用户,并且给Neutron授权Admin role,创建服务向Keystone暴露Endpoint。

[root@localhost  ~]# openstack user create --domain default --password-prompt neutron
[root@localhost  ~]# openstack role add --project service --user neutron admin
[root@localhost  ~]# openstack service create --name neutron \
 –description "OpenStack Networking" network
[root@localhost  ~]# openstack endpoint create --region RegionOne network public \
                    http://192.168.4.145:9696
[root@localhost  ~]# openstack endpoint create --region RegionOne network internal \
                    http://192.168.4.145:9696
[root@localhost  ~]# openstack endpoint create --region RegionOne network admin \
                    http://192.168.4.145:9696

12.3 安装Neutron组件服务

安装软件包,编辑Neutron配置文件。

[root@localhost  ~]# yum install openstack-neutron openstack-neutron-ml2 \
                    openstack-neutron-openvswitch ebtables
[root@localhost  ~]# vi /etc/neutron/neutron.conf
[DEFAULT]
auth_strategy = keystone
core_plugin = ml2
service_plugins = router
allow_overlapping_ips = true
notify_nova_on_port_status_changes = true
notify_nova_on_port_data_changes = true
transport_url = rabbit://openstack:tera123@192.168.4.145
[database]
connection = mysql+pymysql://neutron:tera123@192.168.4.145/neutron
[keystone_authtoken]
www_authenticate_uri = http://192.168.4.145:5000
auth_url = http://192.168.4.145:5000
memcached_servers = 192.168.4.145:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = neutron
password = 123456
[nova]
auth_url = http://192.168.4.145:5000
auth_type = password
project_domain_name = default
user_domain_name = default
region_name = RegionOne
project_name = service
username = nova
password = 123456

[root@localhost  ~]# vi /etc/neutron/plugins/ml2/ml2_conf.ini
[ml2]
type_drivers = flat,vlan,vxlan
tenant_network_types = vxlan
mechanism_drivers = openvswitch,l2population
extension_drivers = port_security
[ml2_type_flat]
flat_networks = provider
[ml2_type_vxlan]
vni_ranges = 1:1000
[securitygroup]
firewall_driver = neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver
enable_ipset = true
enable_security_group = true

[root@localhost  ~]# vi /etc/neutron/plugins/ml2/openvswitch_agent.ini
[agent]
tunnel_types = vxlan
l2_population = true
arp_responder = true
[ovs]
bridge_mappings = provider:br-provider
datapath_type = system
local_ip = 192.168.4.145
[securitygroup]
enable_security_group = True
firewall_driver = neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver

[root@localhost  ~]# vi /etc/neutron/l3_agent.ini
[DEFAULT]
interface_driver = openvswitch
external_network_bridge  =

[root@localshot  ~]# vi /etc/neutron/dhcp_agent.ini
[DEFAULT]
interface_driver = openvswitch
dhcp_driver = neutron.agent.linux.dhcp.Dnsmasq
enable_isolated_metadata = true

[root@localshot  ~]# vi /etc/neutron/metadata_agent.ini
[DEFAULT]
nova_metadata_host = 192.168.4.145
metadata_proxy_shared_secret = tera123

[root@localhost  ~]# vi /etc/nova/nova.conf
[neutron]
url=http://192.168.4.145:9696
auth_type=password
auth_url=http://192.168.4.145:5000
project_name=service
project_domain_name=default
username=neutron
user_domain_name=default
password=123456
region_name=RegionOne
service_metadata_proxy = true
metadata_proxy_shared_secret = tera123

12.4 网桥绑定物理网卡

添加br-provider网桥并且绑定物理网卡eno2。

[root@localhost  ~]# ovs-vsctl add-br br-provider
[root@localhost  ~]# ovs-vsctl add-port br-provider eno2

12.5 修改系统内核参数

修改内核参数确保Linux操作系统内核支持网桥过滤器。

[root@localhost  ~]# vi /etc/sysctl.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
[root@localhost  ~]# modprobe br_netfilter
[root@localhost  ~]# sysctl -p

12.6 创建符号链接

网络符文初始化脚本需要plugin.ini指向ML2插件配置文件的符号链接。

[root@localhost  ~]# ln -s /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugin.ini

12.7 同步数据库

导入Neutron库SQL。

[root@localhost  ~]# su -s /bin/sh -c "neutron-db-manage --config-file /etc/neutron/neutron.conf \  --config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade head" neutron

12.8 启动Neutron服务、

System管理Neutron服务。

[root@localhost  ~]# systemctl restart openstack-nova-api
[root@localshot  ~]# systemctl start neutron-server neutron-openvswitch-agent \
neutron-dhcp-agent neutron-metadata-agent neutron-l3-agent
[root@localshot  ~]# systemctl enable neutron-server neutron-openvswitch-agent \
neutron-dhcp-agent neutron-metadata-agent neutron-l3-agent

13 Neutron(计算节点)

13.1 安装Neutron组件服务

安装Neutron服务,并编辑配置文件。

[root@localhost  ~]# yum -y install openstack-neutron-openvswitch ebtables ipset -y
[root@localhost  ~]# vi /etc/neutron/neutron.conf
[DEFAULT]
state_path = /var/lib/neutron
auth_strategy = keystone
transport_url = rabbit://openstack:tera123@192.168.4.145
[keystone_authtoken]
www_authenticate_uri = http://192.168.4.145:5000
auth_url = http://192.168.4.145:5000
memcached_servers = 192.168.4.145:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = neutron
password = 123456
[oslo_concurrency]
lock_path = $state_path/lock

[root@localhost  ~]# vi /etc/neutron/plugins/ml2/openvswitch_agent.ini
[ovs]
local_ip  =  192.168.4.144
[agent]
tunnel_types  =  vxlan
l2_population  =  True
prevent_arp_spoofing = True
[securitygroup]
enable_security_group = True
firewall_driver = neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver

[root@localhost  ~]# vi /etc/noca/nova.conf
[neutron]
url=http://192.168.4.145:9696
auth_type=password
auth_url=http://192.168.4.145:5000
project_name=service
project_domain_name=default
username=neutron
user_domain_name = default
password=123456
region_name=RegionOne

13.2 修改系统内核参数

修改内核参数确保Linux操作系统内核支持网桥过滤器。

[root@localhost  ~]# vi /etc/sysctl.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
[root@localhost  ~]# modprobe br_netfilter
[root@localhost  ~]# sysctl -p

13.3 启动Neutron服务

启动Neutron服务。

[root@localhost  ~]# systemctl restart openstack-nova-compute
[root@localshot  ~]# systemctl start neutron-openvswitch-agent
[root@localshot  ~]# systemctl enable neutron-openvswitch-agent

13.4 验证Neutron服务(控制节点)

验证Neutron agent启动状态。

[root@localhost  ~]# openstack network agent list
+--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+
| ID                                   | Agent Type         | Host       | Availability Zone | Alive | State | Binary                    |
+--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+
| 2df818b0-e911-4e5a-8c53-1ae85e387caa | Open vSwitch agent | controller | None              | :-)   | UP    | neutron-openvswitch-agent |
| 8a1711ee-9772-4931-af61-eed89024ff04 | L3 agent           | controller | nova              | :-)   | UP    | neutron-l3-agent          |
| cff39707-e34b-4cc7-9be0-95bbe281a5b9 | Metadata agent     | scontroller | None              | :-)   | UP    | neutron-metadata-agent    |
| e4949796-9f35-40b4-aba0-781ee7ce9a31 | DHCP agent         | controller | nova              | :-)   | UP    | neutron-dhcp-agent        |
| efd5fa9a-9b0e-447f-8ddc-13755efdd999 | Open vSwitch agent | compute    | None              | :-)   | UP    | neutron-openvswitch-agent |
+--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+

14 Horizon(控制节点)

14.1 安装Horizon软件包

安装软件包并编辑配置文件。

[root@localhost  ~]# yum install -y openstack-dashboard
[root@localhost  ~]# vi /etc/openstack-dashboard/local_settings
OPENSTACK_HOST = "192.168.4.145"
ALLOWED_HOSTS = ['*', 'localhost']  
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': '192.168.4.145:11211',
    },
}
OPENSTACK_KEYSTONE_URL = "http://%s:5000/v3" % OPENSTACK_HOST
OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True
OPENSTACK_API_VERSIONS = {
    "identity": 3,
    "image": 2,
    "volume": 2,
}
OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = 'Default'
OPENSTACK_KEYSTONE_DEFAULT_ROLE = "user"
OPENSTACK_NEUTRON_NETWORK = {
    'enable_router': True,
    'enable_quotas': True,
    'enable_ipv6': True,
    'enable_distributed_router': False,
    'enable_ha_router': False,
'enable_fip_topology_check': True,
}

[root@localhost  ~]# vi /etc/httpd/conf.d/openstack-dashboard.conf
WSGIDaemonProcess dashboard
WSGIProcessGroup dashboard
WSGISocketPrefix run/wsgi
WSGIApplicationGroup %{GLOBAL}
WSGIScriptAlias /dashboard \
usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi
Alias /dashboard/static /usr/share/openstack-dashboard/static
<Directory /usr/share/openstack-dashboard/openstack_dashboard/wsgi>
  Options All
  AllowOverride All
  Require all granted
</Directory>
<Directory /usr/share/openstack-dashboard/static>
  Options All
  AllowOverride All
  Require all granted
</Directory>

14.2 启动Horizon

启动Horizon服务。

[root@localhost  ~]# systemctl restart httpd  memcached

14.3 验证Horizon

登录Web端URL:http://192.168.4.145/dashboard,验证Horizon组件。

登录Web端验证Horizon组件

15 参考文献

OpenStack官网:www.openstack.org

更多相关内容,请访问:A-Lab

配置指导:OpenStack 安装报错情况整理

1 MySQL

1.1 MySQL连接数

大多数OpenStack服务都使用MySQL数据库来存储信息,各组件直接的调用都需要修改MySQL的存储信息或者验证存储信息。MySQL连接数不够会杀死正在执行的SQL,导致各组件之间的调用失败。

解决这个问题需要调整MySQL配置文件中最max_connections参数和MySQL system参数。

[root@localhost  ~]# vi /etc/my.cnf
[mysqld]
max_connections=1024
[root@localhost  ~]# vi /usr/lib/systemd/system/mariadb.service
[serivce]
LimitNOFILE=65535
LimitNPROC=65535

1.2 MySQL Client连接失败

 ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/home/mysql/mysql.sock’

MySQL Client在登录的时候会默认去找/var/lib这个目录找mysqld.sock文件,如果Mysql启动失败或者修改了MySQL存储路径自然就找不到了。添加如下配置:

[root@localhost  ~]# vi /etc/my.cnf.d/client.cnf
[client-mariadb]
socket=/home/mysql/mysql.sock
[root@localhost  ~]# systemctl start mariadb

2 RabbitMQ

2.1 RabbitMQ用户名不匹配

OpenStack使用RabbitMQ来协调服务之间的操作和状态信息。消息队列服务通常在控制器节点运行。RabbitMQ需要关注的是用户名和密码问题。如果用户名和密码错误,各组件直接的调用都会失败,所有虚拟机无法访问。这时候需要修改RabbitMQ用来提供服务的用户名和密码:

[root@localhost  ~]# rabbitmqctl list_users
[root@localhost  ~]# rabbitmqctl change_password username ‘newpasswd’

2.2 RabbitMQ端口不通

ERROR oslo.messaging._drivers.impl_rabbit [-] [94fc1201-373b-451f-a9e2-46fc81b5de20] AMQP server on controller:5672 is unreachable: [Errno 111] ECONNREFUSED. Trying again in 24 seconds.: error: [Errno 111] ECONNREFUSED

RabbitMQ 5672端口不可用。可能出于两种情况:一是RabbitMQ启动失败,状态错误。查看RbbitMQ状态。二是5672端口被墙,关闭firewalld防火墙并且查看iptables规则。

[root@localhost  ~]# systemctl  status  rabbitmq-server
[root@localhost  ~]# systemctl  stop firewadll
[root@localhost  ~]# iptables -S
[root@localhost  ~]# iptables -F

3 Memcached

Memcached的作用是缓存身份服务身份验证机制的令牌。在正常运行中Memached一般不会出现问题。需要注意的一点是要确保端口不被墙。

4 Etcd

4.1 Etcd集群状态

cluster may be unhealthy: failed to list members

Error: client: etcd cluster is unavailable or misconfigured; error #0: dial tcp 127.0.0.1:2379: getsockopt: connection refused ;

error #1: dial tcp 127.0.0.1:4001: getsockopt: connection refused

error #0: dial tcp 127.0.0.1:2379: getsockopt: connection refused

error #1: dial tcp 127.0.0.1:4001: getsockopt: connection refused

OpenStack官网配置错,因为在Etcd的配置文件中的ETCD_LISTEN_CLIENT_URLS参数中,只写入了http://ip:2379,没有写入http://127.0.0.1:2379,添加后集群正常。

[root@localhost  ~]# vi /etc/etcd/etcd.conf
ETCD_DATA_DIR="/home/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="http://192.168.4.145:2380"
ETCD_LISTEN_CLIENT_URLS="http://192.168.4.145:2379,http://127.0.0.1:2379"
ETCD_NAME="controller"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.4.145:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.4.145:2379"
ETCD_INITIAL_CLUSTER="controller=http://192.168.4.145:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"

5 Libvirtd

5.1 Libvirtd用户与用户组

KVM cannot access storage file (as uid:107,gid:107)permission denied

这一系列没有权限而导致的创建虚机失败需要调整libvirt的默认权限。

[root@localhost  ~]# vi /etc/libvirt/qemu.conf
user=root
group=root

5.2 Libvirtd用户与用户组

Libvirtd Could not reopen file:Permission denied

dynamic_ownership = 1这个参数意思是Libvirtd是否有权限动态修改文件所有权,默认为1。在一般情况下user和group设置为root是拥有所有文件的所有权。但是,因为这个参数的存在导致创建虚拟机报错。当注释后,创建虚拟机正常,可能是因为版本问题而导致的bug。

[root@localhost  ~]# vi /etc/libvirt/qemu.conf
user=root
group=root
#dynamic_ownership = 1

6 Keystone

6.1 同步数据库问题

OperationalError) no such table: project u’INSERT INTO project (id, name, domain_id, des

cription, enabled, extra) VALUES (?, ?, ?, ?, ?, ?)’ (’70c0487ba99743719d6721a34560fca2′, u’admin’, ‘default’, u’Admin Tenant’, 1, ‘{}’)

这个问题是因为Kyestone中表不存在,也就是说同步Keystone数据库失败导致,需要再次同步数据库。如果再次失败需要检查配置文件数据库连接配置是否有错误。

[root@localhost  ~]# mysql -uroo -p
MariaDB [ (none) ] use keystone;
MariaDB [ (none) ] show tables;
Empty set (0.00 sec)
[root@localhost  ~]# su -s /bin/sh -c "keystone-manage db_sync" keystone

6.2 OpenStackcliet错误码

下面是在创建用户或者service等服务时可能出现的错误码和解决方式。

401 #验证失败,keystone相关用户账户密码设置错误,时间不同步,或者输入的项目名称不对。

403 #可能未初始化OS_token变量,需要使用source命令使其生效,也可能是配置的配置文件未生效,需要重启相关服务。

409 #keystone创建用户,用户已存在。

500 #服务器内部错误,服务配置有问题,看日志,检查配置。

503 #keystone相关账户密码设置有问题,请将相关的账户删除,重新创建即可。

7 Nova

7.1 MySQL连接丢失

ERROR oslo_db.sqlalchemy.engines [-] Database connection was found disconnected; reconnecting: DBConnectionError: (pymysql.err.OperationalError) (2013, ‘Lost connection to MySQL server during query’) [SQL: u’SELECT 1′] (Background on this error at: http://sqlalche.me/e/e3q8)

字面意思是在查询的过程中丢失MySQL连接,即某个MySQL长连接很久没有新的请求发起,达到了server端的timeout,被server强行关闭。解决这个问题需要在MySQL配置文件中修改wait_timeout参数。

[root@localhost  ~]# vi /etc/my.cnf
[mysqld]
wait_timeout=28800

7.2 新增节点报错

ERROR nova.scheduler.client.report [req-fb678c94-091f-4dd3-bd44-49068015a07e – – – – -] [req-a7dd9b65-4ef2-4822-8110-f4a311839683] Failed to create resource provider record in placement API for UUID 73542ad1-f32b-4ba8-a62c-98ec704234c3. Got 409: {“errors”: [{“status”: 409, “request_id”: “req-a7dd9b65-4ef2-4822-8110-f4a311839683”, “detail”: “There was a conflict when trying to complete your request.\n\n Conflicting resource provider name: compute already exists.  “, “title”: “Conflict”}]}.

一台计算机点故障导致不能继续工作,将其移出集群,节点恢复后再重新加入发现报错。这主要原因是因为数据库中数据冲突导致。更新nova库、nova_api库中对应resource_providers表中的UUID即可。

[root@localhost  ~]# mysql -uroot -p
MariaDB [nova_api]> update resource_providers set uuid='4d9ed4b4-f3a2-4e5d-9d8e-2f657a844a04' where name='compute' and uuid='e131e7c4-f7db-4889-8c34-e750e7b129da';

7.3 Nova-vnc报错

INFO nova.console.websocketproxy [req-a9ef9047-7b5b-4251-b2c3-3de8fa2db7d1 – – – – -] handler exception: [Errno 113] EHOSTUNREACH

在OpenStack上创建虚机成功,登录控制台时显示vnc报错1006,查看Nova日志,确定是因为计算节点防火墙没有关闭或者iptables没有过滤vnc端口。

[root@localhost  ~]# systemct stop firewalld
[root@localhost  ~]# iptables -I INPUT -p tcp --ports 5900:6100  -j ACCEPT

8 Glance

8.1 权限问题

Glance报错基本都是因为权限问题而导致的。如果修改了Glance存储路径,需要给修改后的路径glance:glance权限。

9       Neutron

9.1       虚拟机不通外网

虚拟机不通外网主要原因有很多,首先网络类型是否误设置为Local:Local型网络只适合虚拟机与虚拟机之间互通,网络所在的网桥不会连接服务器的物理网卡,所以Local型网络的虚拟机是与外网不通的。

  • 虚拟机是否启动,如果它没有运行,可以通过查看Nova日志查看问题。
[root@localhost  ~]# openstack servier list
[root@localhost  ~]# tail -f /var/log/nova/nova-compute
  • 安全组问题,在默认安全组下可能不允许一些协议通过,所以需要配置安全组。
[root@localhost  ~]# openstack security group show default
  • 查看Neutron各agent状态是否正确,如果down,查看日志解决。
[root@localhost  ~]# openstack network agent list

更多相关内容,请访问:A-Lab

配置指导:OpenStack yum源安装部署

1 OpenStack简介

OpenStack是一个由NASA(美国国家航空航天局)和Rackspace合作研发并发起的,以Apache许可证授权的自由软件和开放源代码项目。OpenStack支持几乎所有类型的云环境,项目目标是提供实施简单、可大规模扩展、丰富、标准统一的云计算管理平台。OpenStack通过各种互补的服务提供了基础设施即服务(IaaS)的解决方案,每个服务提供API以进行集成。

2 OpenStack架构图

整个OpenStack是由控制节点,计算节点,网络节点,存储节点四大部分组成。控制节点负责对其余节点的控制,包含虚拟机建立,迁移,网络分配,存储分配等等。计算节点负责虚拟机运行网络节点负责对外网络与内网络之间的通信存储节点负责对虚拟机的额外存储管理。其中各组件架构图如下:

OpenStack架构图

3 OpenStack必要组件

  • 认证管理服务,提供了Openstack其余所有组件的认证信息/令牌的管理、创建、修改等等,使用MySQL等数据库存储认证信息
  • 计算管理服务,是Openstack计算的弹性控制,提供虚拟机的创建、运行、迁移、快照等围绕虚拟机的服务,并提供API与控制节点对接,由控制节点下发任务,使用nova-api进行通信
  • 网络管理服务,提供了对网络节点的网络拓扑管理,负责管理私有网络与公有网络的通信,以及管理虚拟机网络之间通信/拓扑、管理虚拟机之上的防火墙等,同时提供Neutron在Horizon的管理界面
  • 镜像管理服务,用于管理虚拟机部署时所能提供的镜像,包含镜像的导入、格式以及制作相应的模板,是一套虚拟机镜像发现、注册、检索系统,所有计算实例都是从Glance镜像启动的
  • 控制台服务,是一个用以管理、控制Openstack服务的Web控制面板,它可以管理实例、镜像、创建密匙对,对实例添加卷、操作Swift容器等,用户还可以在控制面板中使用终端(console)或VNC直接访问实例

4 OpenStack基础服务

  • OpenStack使用SQL数据库来存储信息。该数据库通常在控制器节点上运行
  • OpenStack使用消息队列来协调服务之间的操作和状态信息。消息队列服务通常在控制器节点上运行
  • 服务的身份服务、身份验证机制使用Memcached来缓存令牌。Memcached服务通常在控制器节点上运行
  • OpenStack服务使用Etcd(分布式可靠的键值存储)进行分布式键锁定,存储配置,跟踪服务活动性和其他情况

5 硬件配置

主机系统网卡1:eno1网卡2:eno2
openstackCentos7.6192.168.4.145192.168.5.145
computeCentos7.6192.168.4.144192.168.5.144

服务器具体配置要求如下:

  • 2个千兆网口
  • 至少8G内存
  • 磁盘至少40G
  • 计算节点的BISO中开启CPU嵌套虚拟化(INTEL叫VT-x,AMD的叫AMD-V)

6 系统优化

主机的优化不单纯只是软硬件的优化,基于操作系统的性能优化也是多方面的,可以从几个方面进行衡量,以更好的提高主机的性能。

6.1 关闭SELinux(控制节点、计算节点)

SELinux不关闭的情况下无法实现,会限制ssh免密码登录。

[root@localhost  ~]#setenforce 0
[root@localhost  ~]# sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux

6.2 关闭防火墙(控制节点、计算节点)

防止安装时出现各个组件的端口不能访问的问题。

[root@localhost  ~]#systemctl stop firewalld && systemctl disable firewalld        

6.3 时间同步(控制节点、计算节点)

同步时间可以有效解决因时间不同而造成的不同步。

[root@localshot  ~]# yum -y install ntp
[root@localhost  ~]# ntpdate ntp1.aliyun.com
[root@localhost  ~]# timedatectl set-timezone Asia/Shanghai

6.4 内核隔离(控制节点、计算节点)

OpenStack部分机器用于做控制节点,大部分机器都是需要运行虚拟化软件,虚拟化平台有大量VM,而宿主机本身的系统也会跑一些服务,那么这就势必会造成VM与宿主机系统之间资源的抢占。我们可以通过修改内核参数指定操作系统使用指定的几个核,解决抢占问题。

[root@localhost  ~]# vi /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT=”isolcpus=8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47”
[root@localhost  ~]# update-grub

6.5 关闭KVM内存共享(计算节点)

内存配置方面,关闭KVM内存共享,打开透明大页,提升主机CPU性能。

[root@localhost  ~]# echo 0>/sys/kernel/mm/ksm/pages_shared
echo 0>/sys/kernel/mm/ksm/pages_sharing
echo always > /sys/kernel/mm/transparent_hugepage/enabled
echo always>/sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
echo 0 > /sys/kernel/mm/transparent_hugepage/khugepaged/defrag

6.6 修改系统打开文件最大数量(计算节点、控制节点)

放开系统打开文件最大数量,防止因达到上限值而导致的进程终止。

[root@localhost  ~]# vi /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535

6.7 降低Swap分区使用率(控制节点、计算节点)

现在服务器的内存一般是上百GB,所以我们可以把这个参数值设置的低一些(如10-30之间),让操作系统尽可能的使用物理内存,降低系统对swap的使用,从而提高宿主机系统和虚拟机的性能。

[root@localhost  ~]# echo 'vm.swappiness=10' >>/etc/sysctl.conf

7 基础服务部署

7.1 安装OpenStack国内yum源(控制节点、计算节点)

安装阿里的OpenStack yum源可以加快各组件的下载速度。

[root@localhost  ~]# cat << EOF >> /etc/yum.repos.d/openstack.repo
[openstack-rocky]
name=openstack-rocky
baseurl=https://mirrors.aliyun.com/centos/7/cloud/x86_64/openstack-rocky/
enabled=1
gpgcheck=0
[qume-kvm]
name=qemu-kvm
baseurl= https://mirrors.aliyun.com/centos/7/virt/x86_64/kvm-common/
enabled=1
gpgcheck=0
EOF

7.2 部署OpenStackClient(控制节点)

[root@localhost  ~]# yum upgrade -y
[root@localhost  ~]# yum install -y python-openstackclient openstack-selinux

7.3 部署MySQL(控制节点)

部署MySQL并且通过修改配置文件更改存储路径。

[root@localhost  ~]# yum install -y mariadb mariadb-server python2-PyMySQL
[root@localhost  ~]# vi /etc/my.cnf.d/openstack.cnf
[mysqld]
bind-address=192.168.4.145
default-storage-engine = innodb
innodb_file_per_table = on
max_connections = 4096
collation-server = utf8_general_ci
character-set-server = utf8
[root@localhost  ~]# vi /etc/my.cnf
[mysqld]
query_cache_size = 0
query_cache_type = OFF
max_connections = 4096

7.4 启动MySQL(控制节点)

修改MySQL用户密码,并且system管理MySQL。

[root@localhost  ~]# systemctl enable mariadb
[root@localhost  ~]# systemctl start mariadb
[root@localhost  ~]# mysql -uroot 
MariaDB [(none)]> update mysql.user set password=password('tera123') where user = 'root';
MariaDB [(none)]> flush privileges;

7.5 部署RabbitMq(控制节点)

部署RabbitMq来协调服务之间的操作和状态信息,并且修改RabbitMq存储路径。

[root@localhost  ~]# yum -y install rabbitmq-server
[root@localhost  ~]# vi /etc/rabbitmq/rabbitmq-env.conf
RABBITMQ_MNESIA_BASE=/var/lib/rabbitmq/mnesia
RABBITMQ_LOG_BASE=/var/lib/rabbitmq/log
[root@localhost  ~]# mkdir -p /var/lib/rabbitmq/mnesia
[root@localhost  ~]# mkdir -p /var/lib/rabbitmq/log
[root@localhost  ~]# chmod -R 755 /var/lib/rabbitmq
[root@localhost  ~]# systemctl enable rabbitmq-server.service
[root@localhost  ~]# systemctl start rabbitmq-server.service

7.6 配置RabbitMq用户 (控制节点)

添加OpenStack用户并且配置用户权限

[root@localhost  ~]# rabbitmqctl add_user openstack tera123
Creating user “openstack” …
[root@localhost  ~]# rabbitmqctl set_permissions openstack “.*” “.*” “.*”
Setting permissions for user “openstack” in vhost “/”…

7.7 部署Memcached(控制节点)

部署Memcached,并修改配置文件。

[root@localhost  ~]# yum -y install memcached
[root@localhost  ~]# vi /etc/sysconfig/memcached
OPTIONS=”-l 127.0.0.1,::1,192.168.4.145”
[root@localhost  ~]# systemctl enable memcached
[root@localhost  ~]# systemctl start memcached

7.8 部署Etcd(控制节点)

部署Etcd,修改配置文件,并且使用system管理。

[root@localhost  ~]# yum -y install etcd
[root@localhost  ~]# vi /etc/etcd/etcd.conf
ETCD_LISTEN_PEER_URLS=http://192.168.4.145:2380
ETCD_LISTEN_CLIENT_URLS="http://192.168.4.145:2379,http://127.0.0.1:2379 "
ETCD_NAME="controller"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.4.145:2380"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.4.145:2379"
ETCD_INITIAL_CLUSTER="controller=http://192.168.4.145:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new”
[root@localhost  ~]# systemctl enable etcd
[root@localhost  ~]# systemctl start etcd

8 Keystone(控制节点)

OpenStack Identity服务提供了一个集成点,用于管理身份验证,授权和服务目录。

Keystone通常是用户与之交互的第一项服务。身份验证后,最终用户可以使用其身份访问其他OpenStack服务。同样,其他OpenStack服务利用Keystone来确保用户是他们所说的人,并发现其他服务在部署中的位置用户和服务可以使用由Keystone管理的服务目录来查找其他服务。

服务目录是OpenStack部署中可用服务的集合。每个服务可以具有一个或多个端点,并且每个端点可以是以下三种类型之一:admin,internal或public。在生产环境中,出于安全原因,不同的终结点类型可能驻留在暴露给不同类型用户的单独网络上。

8.1 MySQL中创建库和权限

在数据库中创建Keystone用户,并且授予用户访问库的权限。

[root@localhost  ~]# mysql -uroot -p
MariaDB [(none)]> create database keystone;
MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' identified by 'tera123';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' identified by 'tera123';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'openstack' identified by 'tera123';

8.2 安装Keystone组件服务

部署openstack-keystone、http、http模块,配置Keystone。

[root@localhost  ~]# yum install openstack-keystone httpd mod_wsgi
[root@localhost  ~]# vi /etc/keystone/keystone.conf
[database]
Connection=mysql+pymysql://keystone:tera123@192.168.4.145/keystone
[token]
Provider=fernet

8.3 配置keystone库

导入keytone库SQL,初始化Fernet秘钥库存储,引导身份服务。

[root@localhost  ~]# su -s /bin/sh -c “keystone-manage db_sync” keystone
[root@localhost ~]# keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone
[root@localhost  ~]# keystone-manage credential_setup --keystone-user keystone --keystone-group keystone
[root@localhost  ~]# keystone-manage bootstrap --bootstrap-password tera123\ 
--bootstrap-admin-url http://192.168.4.145:5000/v3/ \
--bootstrap-internal-url http://192.168.4.145:5000/v3/ \
--bootstrap-public-url http://192.168.4.145:5000/v3/ \
--bootstrap-region-id RegionOne

8.4 配置Apache HTTP服务器

[root@localhost  ~]# vi /etc/httpd/conf/httpd.conf
ServerName 192.168.4.145
[root@localhost  ~]# ln -s /usr/share/keystone/wsgi-keystone.conf  /etc/httpd/conf.d/

8.5 完成部署

System管理Keystone并且配置管理账户。

[root@localhost  ~]# systemctl enable httpd.service
[root@localhost  ~]# systemctl start httpd.service
[root@localhost  ~]# vi admin-openrc
export OS_USERNAME=admin
export OS_PASSWORD=tera123
export OS_PROJECT_NAME=admin
export OS_USER_DOMAIN_NAME=Default
export OS_PROJECT_DOMAIN_NAME=Default
export OS_AUTH_URL=http://192.168.4.145:5000/v3
export OS_IDENTITY_API_VERSION=3

8.6 创建Service项目

[root@localhost  ~]# openstack project create --domain default \
                    --description “Service Project” service

8.7 验证Keystone

[root@localhost  ~]# openstack user list
+----------------------------------------------------------------+--------------+
| ID                                  | Name  |
| 57341d3e37eb4dc997624f9502495e44 | admin  |
+-----------------------------------------------------------------+--------------+

9 Glance(控制节点)

Glance使用户可以发现、注册和检索虚拟机镜像。它提供了 REST API,使您可以查询虚拟机镜像元数据并检索实际镜像。您可以将通过Image服务提供的虚拟机存储在从简单文件系统到对象存储系统(如OpenStack Object Storage)的各种位置。Glance由以下部分组成:

  • glance-api:用于接收Glance发现、检索和存储的Image API调用
  • glance-registry:存储、处理和检索有关Glance的元数据。元数据包括大小和类型等项目

9.1 MySQL中创建库和权限

在数据库中创建Glance用户,并且授予用户访问库的权限。

[root@localhost  ~]# mysql -uroot -p
MariaDB [(none)]> create database glance;
MariaDB [(none)]>GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost' identified by 'tera123';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'%' identified by 'tera123';
MariaDB [(none)]>GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'openstack' identified by 'tera123';

9.2 创建用户、服务

创建Glance用户,并且给Glance授权Admin role,创建服务向Keystone暴露Endpoint。

[root@localhost  ~]# openstack user create --domain default --password-prompt glance
[root@localhost  ~]# openstack role add --project service --user glance admin
[root@localhost  ~]# openstack service create --name glance \
 --description “OpenStack Image” image
[root@localhost  ~]# openstack endpoint create --region RegionOne image public \
                    http://192.168.4.145:9292
[root@localhost  ~]# openstack endpoint create --region RegionOne image internal \
                    http://192.168.4.145:9292
[root@localhost  ~]# openstack endpoint create --region RegionOne image admin \
                    http://192.168.4.145:9292

9.3 安装Glance组件服务

安装软件包,编辑Glance配置文件。

[root@localhost  ~]# yum install -y openstack-glance
[root@localhost  ~]# vi /etc/glance/glance-api.conf
[database]
connection = mysql+pymysql://glance:tera123@192.168.4.145/glance
[glance_store]
stores = file,http
default_store = file
[keystone_authtoken]
www_authenticate_uri = http://192.168.4.145:5000
auth_url = http://192.168.4.145:5000
memcached_servers = 192.168.4.145:11211
auth_type = password
project_domain_name = Default
user_domain_name = Default
project_name = service
username = glance
password = 123456                              #创建Glance用户时填入的密码
[paste_deploy]
flavor = keystone
[root@loaclhost  ~]# vi /etc/glance/glance-registry.conf
[database]
connection = mysql+pymysql://glance:tera123@192.168.4.145/glance
[keystone_authtoken]
www_authenticate_uri = http://192.168.4.145:5000
auth_url = http://192.168.4.145:5000
memcached_servers = 192.168.4.145:11211
auth_type = password
project_domain_name = Default
user_domain_name = Default
project_name = service
username = glance
password = 123456
[paste_deploy]
flavor = keystone

9.4 同步数据库

导入Glance库的SQL文件,启动Glance服务。

[root@localhost  ~]# su -s /bin/sh -c “glance-manage db_sync” glance
[root@localhost  ~]# systemctl start openstack-glance-api openstack-glance-registry
[root@localhost  ~]# systemctl enable openstack-glance-api openstack-glance-registry

9.5 验证Glance服务

上传镜像验证Glance服务可用性。

[root@localhost  ~]# wget http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img
[root@localhost  ~]# openstack image create "cirros" --file cirros-0.3.4-x86_64-disk.img --disk-format qcow2 --container-format bare --public
[root@localhost  ~]# openstack image list
+------------------------------------------------------------------+----------------------------+------------+
| ID                                   | Name          | Status  |
+------------------------------------------------------------------+----------------------------+------------+
| 6a1ba286-5ef2-409f-af11-5135e21adb4d | cirros          | active  |
+------------------------------------------------------------------+----------------------------+-------------+

10 Nova(控制节点)

使用OpenStack Compute托管和管理云计算系统。OpenStack Compute是基础架构即服务(IaaS)系统的主要部分。主要模块是用Python实现的。Nova由以下部分组成:

  • nova-api:接收并响应最终用户的compute调用。该服务支持OpenStack Compute API。它执行一些策略并启动大多数编排活动,例如运行实例
  • nova-api-metadata:接收来自实例的元数据请求
  • nova-compute:通过守护程序API创建和终止虚拟机实例的辅助程序守护程序
  • nova-placement-api:跟踪每个提供商的库存和使用情况
  • nova-scheduler:从队列中获取虚拟机实例请求,并通过计算确定它在哪台服务器主机上运行
  • nova-conductor:中介nova-compute服务与数据库之间的交互。消除了对数据库的直接访问
  • nova-consoleauth:为控制台代理提供的用户授权令牌
  • nova-novncproxy:提供用于通过VNC连接访问正在运行的实例的代理

10.1 MySQL中创建库和权限

在数据库中创建Glance用户,并且授予用户访问库的权限。

[root@localhost  ~]# mysql -uroot -p
MariaDB [(none)]> create database nova_api;
MariaDB [(none)]> create database nova;
MariaDB [(none)]> create database nova_cell0;
MariaDB [(none)]> create database placement;
MariaDB[(none)]>GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'localhost' identified by 'tera123';
MariaDB[(none)]>GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'%' identified by 'tera123';
MariaDB[(none)]>GRANT ALL PRIVILEGES ON nova_api.* TO 'nova'@'openstack' identified by 'tera123';

MariaDB[(none)]>GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'localhost' identified by 'tera123';
MariaDB[(none)]>GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'%' identified by 'tera123';
MariaDB[(none)]>GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'openstack' identified by 'tera123';

MariaDB[(none)]>GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'localhost' identified by 'tera123';
MariaDB[(none)]>GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'%' identified by 'tera123';
MariaDB[(none)]>GRANT ALL PRIVILEGES ON nova_cell0.* TO 'nova'@'openstack' identified by 'tera123';

MariaDB[(none)]>GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'localhost' identified by 'tera123';
MariaDB[(none)]>GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'%' identified by 'tera123';
MariaDB[(none)]>GRANT ALL PRIVILEGES ON placement.* TO 'placement'@'openstack' identified by 'tera123';

10.2 创建Nova用户、服务

创建Nova用户,并且给Glance授权Admin role,创建服务向Keystone暴露Endpoint。

[root@localhost  ~]# openstack user create --domain default --password-prompt nova
[root@localhost  ~]# openstack role add --project service --user nova admin
[root@localhost  ~]# openstack service create --name nova \
 --description “OpenStack compute” compute
[root@localhost  ~]# openstack endpoint create --region RegionOne compute public \
                    http://192.168.4.145:8774/v2.1
[root@localhost  ~]# openstack endpoint create --region RegionOne compute internal \
                    http://192.168.4.145:8774/v2.1
[root@localhost  ~]# openstack endpoint create --region RegionOne compute admin \
                    http://192.168.4.145:8774/v2.1

10.3 创建Placement用户、服务

创建Placement用户,并给Placement授权Admin role,创建服务向Keystone暴露Endpoint。

[root@localhost  ~]# openstack user create --domain default --password-prompt placement
[root@localhost  ~]# openstack role add --project service --user placement admin
[root@localhost  ~]# openstack service create --name placement \
 --description “Placement API” placement
[root@localhost  ~]# openstack endpoint create --region RegionOne placement public \
                    http://192.168.4.145:8778
[root@localhost  ~]# openstack endpoint create --region RegionOne placement internal \
                    http://192.168.4.145:8778
[root@localhost  ~]# openstack endpoint create --region RegionOne placement admin \
                    http://192.168.4.145:8778

10.4 安装Nova组件服务

安装Nova组件并且编辑配置文件。

[root@localhost  ~]# yum install openstack-nova-api openstack-nova-conductor \
openstack-nova-console openstack-nova-novncproxy \
openstack-nova-scheduler openstack-nova-placement-api -y
[root@localhost  ~]# vi /etc/nova/nova.conf
[DEFAULT]
my_ip=192.168.4.145
use_neutron=true
firewall_driver=nova.virt.firewall.NoopFirewallDriver
enabled_apis=osapi_compute,metadata
transport_url=rabbit://openstack:tera123@192.168.4.145
[api]
auth_strategy=keystone
[api_database]
connection=mysql+pymysql://nova:tera123@192.168.4.145/nova_api
[database]
connection= mysql+pymysql://nova:tera123@192.168.4.145/nova
[glance]
api_servers= http://192.168.4.145:9292
[keystone_authtoken]
www_authenticate_uri = http://192.168.4.145:5000
auth_url=http://192.168.4.145:5000/v3
memcached_servers= 192.168.4.145:11211
auth_type=password
project_domain_name = Default
user_domain_name = Default
project_name = service
username = nova
password = 123456
[placement]
region_name = RegionOne
user_domain_name = Default
auth_type=password
auth_url=http://192.168.4.145:5000/v3
project_name=service
project_domain_name=Default
username=placement
password=123456
[placement_database]
connection= mysql+pymysql://placement:tera123@192.168.4.145/placement
[scheduler]
discover_hosts_in_cells_interval= 300                     #控制节点自动发现compute,可注释
[vnc]
enabled=true
server_listen=$my_ip
server_proxyclient_address=$my_ip

10.5 配置Placement API

通过将以下配置添加到来启用对Placement API的访问。

[root@localhost  ~]# vi /etc/httpd/conf.d/00-nova-placement-api.conf
Listen 8778
<VirtualHost *:8778>
  <Directory /usr/bin>
   <IfVersion >= 2.4>
      Require all granted
   </IfVersion>
   <IfVersion < 2.4>
      Order allow,deny
      Allow from all
   </IfVersion>
 </Directory>
  WSGIProcessGroup nova-placement-api
  WSGIApplicationGroup %{GLOBAL}
  WSGIPassAuthorization On
  WSGIDaemonProcess nova-placement-api processes=3 threads=1 user=nova group=nova
  WSGIScriptAlias / /usr/bin/nova-placement-api
  <IfVersion >= 2.4>
    ErrorLogFormat "%M"
  </IfVersion>
  ErrorLog /var/log/nova/nova-placement-api.log
  #SSLEngine On
  #SSLCertificateFile ...
  #SSLCertificateKeyFile ...
</VirtualHost>
Alias /nova-placement-api /usr/bin/nova-placement-api
<Location /nova-placement-api>
  SetHandler wsgi-script
  Options +ExecCGI
  WSGIProcessGroup nova-placement-api
  WSGIApplicationGroup %{GLOBAL}
  WSGIPassAuthorization On
</Location>

10.6 同步数据库

导入nova-api、nova、cell0、placement库SQL。

[root@localhost  ~]# su -s /bin/sh -c “nova-manage api_db sync” nova
[root@localhost  ~]# su -s /bin/sh -c “nova-manage cell_v2 map_cell0” nova
[root@localhost  ~]# su -s /bin/sh -c “nova-manage cell_v2 create_cell –name-cell1 --verbose” nova  
[root@localhost  ~]# su -s /bin/sh -c “nova-manage db sync” nova 

10.7 验证Nova服务

验证nova cell0和cell1是否正确注册,并启动Nova服务。

[root@openstack ~]# su -s /bin/sh -c "nova-manage cell_v2 list_cells" nova
+-------+--------------------------------------+---------------------------------------+----------------------------------------------------+----------+
|  Name |                 UUID                 |             Transport URL             |                Database Connection                 | Disabled |
+-------+--------------------------------------+---------------------------------------+----------------------------------------------------+----------+
| cell0 | 00000000-0000-0000-0000-000000000000 |                 none:/                | mysql+pymysql://nova:****@192.168.4.145/nova_cell0 |  False   |
| cell1 | 510ecc1a-4112-4832-b5a5-4f6d4581c545 | rabbit://openstack:****@192.168.4.145 |    mysql+pymysql://nova:****@192.168.4.145/nova    |  False   |
+-------+--------------------------------------+---------------------------------------+----------------------------------------------------+----------+
[root@localhost  ~]# systemctl enable openstack-nova-api.service   \
openstack-nova-consoleauth openstack-nova-scheduler.service \
                    openstack-nova-conductor.service openstack-nova-novncproxy.service
[root@localhost  ~]# systemctl start openstack-nova-api.service \
  openstack-nova-consoleauth   openstack-nova-scheduler.service\
  openstack-nova-conductor.service openstack-nova-novncproxy.service

11 Nova(计算节点)

11.1 安装Nova组件服务

安装Nova组件并且编辑配置文件。

[root@localhost  ~]# yum install openstack-nova-compute -y
[root@localhost  ~]# vi /etc/nova/nova.conf
[DEFAULT]
my_ip=192.168.4.144
use_neutron=true
firewall_driver=nova.virt.firewall.NoopFirewallDriver
enabled_apis=osapi_compute,metadata
transport_url=rabbit://openstack:tera123@192.168.4.145
[api]
auth_strategy=keystone
[glance]
api_servers=http://192.168.4.145:9292
[keystone_authtoken]
www_authenticate_uri = http://192.168.4.145:5000
auth_url=http://192.168.4.145:5000/v3
memcached_servers=192.168.4.145:11211
auth_type=password
project_domain_name = Default
user_domain_name = Default
project_name = service
username = nova
password = 123456
[placement]
region_name = RegionOne
project_domain_name = Default
project_name = service
auth_type = password
user_domain_name = Default
auth_url = http://192.168.4.145:5000/v3
username = placement
password = 123456
[vnc]
enabled=true
server_listen=0.0.0.0
server_proxyclient_address=$my_ip
novncproxy_base_url=http://192.168.4.145:6080/vnc_auto.html

11.2 检测是否支持虚拟化

如果不支持虚拟化,则要配置新的参数。

[root@localhost  ~]# egrep -c ‘(vmx|svm)’ /proc/cpuinfo
[root@localshot  ~]# vi /etc/nova/nova.conf
[libvirt]
virt_type = qemu-

11.3 启动Nova服务

System管理Nova。

[root@localhost  ~]# systemctl enable libvirtd openstack-nova-compute
[root@localshot  ~]# systemctl start libvirtd openstack-nova-compute

11.4 发现计算节点(控制节点)

在控制节点确认计算节点。

[root@localhost  ~]# openstack compute service list --service nova-compute
[root@localshot  ~]# su -s /bin/sh -c “nova-manage cell_v2 discover_hosts --verbose” nova
Found 2 cell mappings.
Skipping cell0 since it does not contain hosts.
Getting computes from cell 'cell1': 54e6c270-7390-4390-8702-02b72874c5a7
Checking host mapping for compute host 'compute': 39d80423-6001-4036-a546-5287c1e93ec5
Creating host mapping for compute host 'compute': 39d80423-6001-4036-a546-5287c1e93ec5
Found 1 unmapped computes in cell: 54e6c270-7390-4390-8702-02b72874c5a7

12 Neutron(控制节点)

OpenStack Networking(neutron)允许创建由其他OpenStack服务管理的接口设备并将其连接到网络。可以实施插件来容纳不同的网络设备和软件,从而为OpenStack体系结构和部署提供灵活性。它包括以下组件:

  • neutron-server:接收API服务器请求并将其路由到适合的OpenStack网络设备以采取措施
  • OpenStack Networking plug-ins and agents:OpenStack通用代理是L3,DHCP和插件代理

12.1 MySQL中创建库和权限

在数据库中创建Neutron用户,并且授予用户访问库的权限。

[root@localhost  ~]# mysql -uroot -p
MariaDB [(none)]> create database neutron;
MariaDB[(none)]>GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost' identified by 'tera123';
MariaDB[(none)]>GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%' identified by 'tera123';
MariaDB[(none)]>GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'openstack' identified by 'tera123'; 

12.2 创建Neutron用户、服务

创建Neutron用户,并且给Neutron授权Admin role,创建服务向Keystone暴露Endpoint。

[root@localhost  ~]# openstack user create --domain default --password-prompt neutron
[root@localhost  ~]# openstack role add --project service --user neutron admin
[root@localhost  ~]# openstack service create --name neutron \
 –description “OpenStack compute” network
[root@localhost  ~]# openstack endpoint create --region RegionOne network public \
                    http://192.168.4.145:9696
[root@localhost  ~]# openstack endpoint create --region RegionOne network internal \
                    http://192.168.4.145:9696
[root@localhost  ~]# openstack endpoint create --region RegionOne network admin \
                    http://192.168.4.145:9696

12.3 安装Neutron组件服务

安装软件包,编辑Neutron配置文件。

[root@localhost  ~]# yum install openstack-neutron openstack-neutron-ml2 \
                    openstack-neutron-linuxbridge ebtables
[root@localhost  ~]# vi /etc/neutron/neutron.conf
[DEFAULT]
auth_strategy = keystone
core_plugin = ml2
service_plugins = router
allow_overlapping_ips = True
notify_nova_on_port_status_changes = true
notify_nova_on_port_data_changes = true
transport_url = rabbit://openstack:tera123@192.168.4.145
[database]
connection = mysql+pymysql://neutron:tera123@192.168.4.145/neutron
[keystone_authtoken]
www_authenticate_uri = http://192.168.4.145:5000
auth_url = http://192.168.4.145:5000
memcached_servers = 192.168.4.145:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = neutron
password = 123456
[nova]
auth_url = http://192.168.4.145:5000
auth_type = password
project_domain_name = default
user_domain_name = default
region_name = RegionOne
project_name = service
username = nova
password = 123456

[root@localhost  ~]# vi /etc/neutron/plugins/ml2/ml2_conf.ini
[ml2]
type_drivers = flat,vlan,vxlan
tenant_network_types = vxlan
mechanism_drivers = linuxbridge,l2population
extension_drivers = port_security
[ml2_type_flat]
flat_networks = provider
[ml2_type_geneve]
vni_ranges = 1:1000
[securitygroup]
enable_ipset = true

[root@localhost  ~]# vi /etc/neutron/plugins/ml2/linuxbridge_agent.ini
[linux_bridge]
physical_interface_mappings = provider:eno2
[securitygroup]
firewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver
enable_security_group = true
[vxlan]
local_ip = 192.168.5.145
l2_population = true

[root@localhost  ~]# vi /etc/neutron/l3_agent.ini
[DEFAULT]
interface_driver = linuxbridge

[root@localshot  ~]# vi /etc/neutron/dhcp_agent.ini
[DEFAULT]
interface_driver = linuxbridge
dhcp_driver = neutron.agent.linux.dhcp.Dnsmasq
enable_isolated_metadata = true

[root@localshot  ~]# vi /etc/neutron/metadata_agent.ini
[DEFAULT]
nova_metadata_host = 192.168.4.145
metadata_proxy_shared_secret = tera123

[root@localhost  ~]# vi /etc/nova/nova.conf
[neutron]
url=http://192.168.4.145:9696
auth_type=password
auth_url=http://192.168.4.145:5000
project_name=service
project_domain_name=default
username=neutron
user_domain_name=default
password=123456
region_name=RegionOne
service_metadata_proxy = true
metadata_proxy_shared_secret = tera123

12.4 修改系统内核参数

修改内核参数确保Linux操作系统内核支持网桥过滤器。

[root@localhost  ~]# vi /etc/sysctl.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
[root@localhost  ~]# modprobe br_netfilter
[root@localhost  ~]# sysctl -p

12.5 创建符号链接

网络符文初始化脚本需要plugin.ini指向ML2插件配置文件的符号链接。

[root@localhost  ~]# ln -s /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugin.ini

12.6 同步数据库

导入Neutron库SQL。

[root@localhost  ~]# su -s /bin/sh -c "neutron-db-manage --config-file /etc/neutron/neutron.conf \  --config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade head" neutron

12.7 启动Neutron服务

System管理Neutron服务。

[root@localhost  ~]# systemctl restart openstack-nova-api
[root@localshot  ~]# systemctl start neutron-server neutron-linuxbridge-agent \
neutron-dhcp-agent neutron-metadata-agent neutron-l3-agent
[root@localshot  ~]# systemctl enable neutron-server neutron-linuxbridge-agent \
neutron-dhcp-agent neutron-metadata-agent neutron-l3-agent

13 Neutron(计算节点)

13.1 安装Neutron组件服务

安装Neutron服务,并编辑配置文件。

[root@localhost  ~]# yum -y install openstack-neutron-linuxbridge ebtables ipset -y
[root@localhost  ~]# vi /etc/neutron/neutron.conf
[DEFAULT]
auth_strategy = keystone
transport_url = rabbit://openstack:tera123@192.168.4.145
[keystone_authtoken]
www_authenticate_uri = http://192.168.4.145:5000
auth_url = http://192.168.4.145:5000
memcached_servers = 192.168.4.145:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = neutron
password = 123456
[oslo_concurrency]
lock_path = $state_path/lock

[root@localhost  ~]# vi /etc/neutron/plugins/ml2/linuxbridge_agent.ini
[linux_bridge]
physical_interface_mappings =provider:eno2
[securitygroup]
firewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver
enable_security_group = true
[vxlan]
enable_vxlan = true
local_ip = 192.168.5.144
l2_population = true

[root@localhost  ~]# vi /etc/noca/nova.conf
[neutron]
url=http://192.168.4.145:9696
auth_type=password
auth_url=http://192.168.4.145:5000
project_name=service
project_domain_name=default
username=neutron
user_domain_name = default
password=123456
region_name=RegionOne

13.2 修改系统内核参数

修改内核参数确保Linux操作系统内核支持网桥过滤器。

[root@localhost  ~]# vi /etc/sysctl.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
[root@localhost  ~]# modprobe br_netfilter
[root@localhost  ~]# sysctl -p

13.3 启动Neutron服务

启动Neutron服务。

[root@localhost  ~]# systemctl restart openstack-nova-compute
[root@localshot  ~]# systemctl start neutron-linuxbridge-agent
[root@localshot  ~]# systemctl enable neutron-linuxbridge-agent

13.4 验证Neutron服务(控制节点)

验证Neutron agent启动状态。

[root@localhost  ~]# openstack network agent list
+--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+
| ID                                   | Agent Type         | Host       | Availability Zone | Alive | State | Binary                    |
+--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+
| 06323fbc-0b13-4c14-a05d-d414678177bf | Linux bridge agent | controller | None              | :-)   | UP    | neutron-linuxbridge-agent |
| 4bd1d3eb-d178-4ff5-8d3f-7307a4415209 | Linux bridge agent | compute    | None              | :-)   | UP    | neutron-linuxbridge-agent |
| 74ba6229-1449-40c7-a0de-53688fbb560a | Metadata agent     | controller | None              | :-)   | UP    | neutron-metadata-agent    |
| d43e223f-c23d-4e60-88b6-ffe12243853f | DHCP agent         | controller | nova              | :-)   | UP    | neutron-dhcp-agent        |
| da0e8763-8082-4a5e-8188-7161d7ad8a05 | L3 agent           | controller | nova              | :-)   | UP    | neutron-l3-agent          |
+--------------------------------------+--------------------+------------+-------------------+-------+-------+---------------------------+
————————————————

14 Horizon(控制节点)

14.1 安装Horizon软件包

安装软件包并编辑配置文件。

[root@localhost  ~]# vi /etc/openstack-dashboard/local_settings
OPENSTACK_HOST = “192.168.4.145”
ALLOWED_HOSTS = ['*', 'localhost']  
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': '192.168.4.145:11211',
    },
}
OPENSTACK_KEYSTONE_URL = "http://%s:5000/v3" % OPENSTACK_HOST
OPENSTACK_KEYSTONE_MULTIDOMAIN_SUPPORT = True
OPENSTACK_API_VERSIONS = {
    "identity": 3,
    "image": 2,
    "volume": 2,
}
OPENSTACK_KEYSTONE_DEFAULT_DOMAIN = 'Default'
OPENSTACK_KEYSTONE_DEFAULT_ROLE = "user"
OPENSTACK_NEUTRON_NETWORK = {
    'enable_router': True,
    'enable_quotas': True,
    'enable_ipv6': True,
    'enable_distributed_router': False,
    'enable_ha_router': False,
'enable_fip_topology_check': True,
}

[root@localhost  ~]# vi /etc/httpd/conf.d/openstack-dashboard.conf
WSGIDaemonProcess dashboard
WSGIProcessGroup dashboard
WSGISocketPrefix run/wsgi
WSGIApplicationGroup %{GLOBAL}
WSGIScriptAlias /dashboard \
usr/share/openstack-dashboard/openstack_dashboard/wsgi/django.wsgi
Alias /dashboard/static /usr/share/openstack-dashboard/static
<Directory /usr/share/openstack-dashboard/openstack_dashboard/wsgi>
  Options All
  AllowOverride All
  Require all granted
</Directory>
<Directory /usr/share/openstack-dashboard/static>
  Options All
  AllowOverride All
  Require all granted
</Directory>

14.2 启动Horizon

启动Horizon服务。

[root@localhost  ~]# systemctl restart httpd  memcached

14.3 验证Horizon

登录Web端URL:http://192.168.4.145/dashboard,验证Horizon组件。

登录Web端

15 参考文献

OpenStack官网:www.openstack.org

更多相关内容,请访问:A-Lab

配置指导:CX-N系列交换机-MC-LAG应用场景配置

1 目的

本文主要讲解企业级SONiC交换机的 MC-LAG解决方案和配置。

2 型号和版本

以下产品可以实现本方案:
CX-N系列交换机
AsterNOS系统软件版本:
AsterNOSv3.1

3 MC-LAG介绍

MC-LAG(Multi Chassis Link Aggregation Group,跨设备链路聚合组)是一种实现跨设备链路聚合的机制,通过将一台设备与另外两台设备进行跨设备链路聚合,保留了普通链路聚合的优点,同时提供了设备级别的冗余。

MC-LAG提供了一种横向虚拟化技术,将两台物理设备虚拟成单台逻辑设备,这台虚拟出来的“单个设备”与其相连的上行或下行设备实现“一对一”链路聚合。如下图所示:

链路聚合

本文所介绍的设备MC-LAG工作模式为:控制面主备模式、数据面双活模式,即:

在控制面需要区分主设备和备设备,主链路和备用链路;

在数据面采用双活方式,两台设备各自决定转发数据流。

4 MC-LAG基础配置说明

Asterfusion交换机运行企业级SONiC(AsterNOS)系统,能够灵活支持MC-LAG组网。

4.1 配置MC-LAG

mclag domain domain-id #创建MC-LAG域并进入视图,当前只支持创建一个域,范围1-4095。

session-timeout timeout #超时时间,单位秒,取值范围为3~3600,默认值为15秒;心跳检测报文的时间间隔应小于MC-LAG会话超时时间的1/3;会话超时时间应为心跳检测报文时间间隔的倍数。

Example:
sonic(config)# mclag domain 10
sonic(mclag-domain)# session-timeout 15

4.2 配置peer-link

vlan vlan-id #在全局视图下配置专用vlan,1-4095。

interface link-aggregation lag-id #创建聚合组,1-9999。

mode static #配置聚合模式为静态

commit #提交配置

switchport trunk vlan vlan-id #指定专用vlan并加入业务vlan

interface ethernet interface-name #进入接口视图

link-aggregation-group lag-id [port-priority port-priority] #加入相应lag,并可指定优先级0-65535,默认255。

startup-delay delay #配置接口延迟,默认为150秒,建议peer-link所在的物理接口上配置延迟值为145秒。

mclag domain domain-id #进入mclag域,id为之前配置的值。

peer-link link-aggregation name #指定peer-link。

commit #提交配置

Example:
sonic(config)# vlan 10
sonic(config-vlan-10)# exit
sonic(config)# interface link-aggregation 10
sonic(config-lagif-10)# mode static
sonic(config-lagif-10)# commit
sonic(config-lagif-10)# switchport trunk vlan 10
sonic(config-lagif-10)# exit
sonic(config)# interface ethernet 0/10
sonic(config-if-0/10)# link-aggregation-group 10
sonic(config-if-0/10)# startup-delay 100
sonic(config-if-0/10)# exit
sonic(config)# mclag domain 10
sonic(mclag-domain)# peer-link link-aggregation 10
sonic(mclag-domain)# commit

4.3 配置心跳检测链路

说明:心跳检测链路用来转发MC-LAG的控制报文,可以与peer-link共用,也可以使用单独的物理链路;

当开启双主检测功能时,要求心跳检测链路与peer-link共用,否则将导致功能失效。

使用单独的物理链路配置心跳检测

interface ethernet interface-name #进入接口视图

ip address A.B.C.D/M #配置接口ip地址

mclag domain domain-id #进入mclag域视图

peer-address A.B.C.D #配置心跳检测链路对端ip地址

local-address A.B.C.D #配置线条检测链路本端ip地址

vrf vrf-name #指定心跳检测链路VRF,默认default

heartbeat-interval interval #配置MC-LAG 心跳检测报文发送间隔时间,单位为秒,取值1~60,默认为1秒;

commit #提交配置

Example:
sonic(config)# interface ethernet 0/11
sonic(config-if-0/11)# ip address 10.0.0.11/24
sonic(config-if-0/11)# exit
sonic(config)# mclag domain 10
sonic(mclag-domain)# peer-address 10.0.0.12
sonic(mclag-domain)# local-address 10.0.0.11
sonic(mclag-domain)# heartbeat-interval 1
sonic(mclag-domain)# commit

使用peer-link配置心跳检测链路

interface vlan vlan-id #进入peer-link专用vlanif配置视图

ip address A.B.C.D/M #配置vlanif的ip地址

mclag domain domain-id #进入mclag域视图

peer-address A.B.C.D #配置心跳检测链路对端ip地址

local-address A.B.C.D #配置线条检测链路本端ip地址

vrf vrf-name #指定心跳检测链路VRF,默认default

commit #提交配置

Example:
sonic(config)# vlan 10
sonic(config-vlan-10)# ip address 10.0.0.11/24
sonic(config- vlan-10)# exit
sonic(config)# mclag domain 10
sonic(mclag-domain)# peer-address 10.0.0.12
sonic(mclag-domain)# local-address 10.0.0.11
sonic(mclag-domain)# commit

4.4 配置MC-LAG成员接口

说明:建议使用低速接口作为MC-LAG成员接口,为提高系统可靠性,建议跨设备聚合组使用动态聚合,并开启LACP短超时。要求部署MC-LAG的两台设备成员物理接口的port ID相同,否则无法正常聚合。

vlan vlan-id #创建业务VLAN,1-4094。

interface link-aggregation lag-id #进入LAG接口配置视图并创建下行聚合组,1-9999。

lacp fast-rate#开启lacp短超时

commit #提交配置

switchport trunk vlan vlan-id #加入业务vlan

mclag domain domain-id #进入mclag域视图

member lag lag-id #添加mclag成员接口

Example:
sonic(config)# vlan 10
sonic(config-vlan-10)# exit
sonic(config)# interface link-aggregation 10
sonic(config-lagif-10)# lacp fast-rate
sonic(config-lagif-10)# commit
sonic(config-lagif-10)# switchport trunk vlan 10
sonic(config-lagif-10)# exit
sonic(config)# mclag domain 10
sonic(mclag-domain)# member lag 10

4.5 配置Monitor Link组

说明:建议在部署MC-LAG的主备设备上配置Monitor Link组,上行口配置为uplink,下行口配置为downlink,开启该功能后,上行口状态down后,下行口会联动down,保证拓扑中出现故障时能够快速收敛。

monitor-link-group group-name [delay-time]#创建monitor-link组,delay-time为可选参数,表示上行口up后下行口up的延迟时间,单位秒,不配置时默认值为0。

interface ethernet interface-name #进入接口视图

monitor-link group-name uplink #配置上行口为uplink

interface link-aggregation lag-id #进入下行聚合组接口配置视图

monitor-link group-name downlink #配置MC-LAG成员接口为downlink

Example:
sonic(config)# monitor-link-group monitor1
sonic(config)# interface ethernet 0/48
sonic(config-if-0/48)# monitor-link monitor1 uplink
sonic(config-if-0/48)# exit
sonic(config)# interface ethernet 0/0
sonic(config-if-0/0)# monitor-link monitor1 downlink

5 MC-LAG典型配置案例

5.1 要求

用户的一台服务器server1运行着重要应用,希望接入的网络稳定可靠,现在用4台Asterfusion sonic交换机搭建网络,将两台leaf设备组成mc-lag与server1连接,测试其中一条链路断开的情况下server1是否会断网,测试过程中用server1与server2进行数据传输测试。

5.2 拓扑图

拓扑图

5.3 测试环境

硬件

名称型号硬件指标数量
spine交换机CX532P-N参见彩页1
Leaf交换机CX308P-48Y-N-V2参见彩页3
服务器X86普通服务器2
光模块多模100G QSFP286
光纤多模100G适用3
光模块多模10G SFP+6
光纤多模10G适用3

软件

软件版本
交换机操作系统AsterNOSv3.1
服务器系统CentOS Linux 7.8.2003
服务器内核 3.10.0-1127.18.2.el7
iperf33.9

管理IP

设备名称接口IP地址
Spine管理口10.230.1.31
Leaf1管理口10.230.1.21
Leaf2管理口10.230.1.22
Leaf3管理口10.230.1.23
Server-1管理口10.230.1.11
Server-2管理口10.230.1.12

设备通信IP

设备名称接口IP地址
SpineEthernet 0/0 10.0.10.201
SpineEthernet 0/410.0.11.201
SpineEthernet 0/810.0.12.201
SpineLoopback 0 172.16.0.1
Leaf1Ethernet 0/0 (Mc-Lag)100.0.10.201
Leaf1Ethernet 0/4(peer-link)11.0.0.11
Leaf1Ethernet 0/4810.0.10.1
Leaf1Loopback 0 172.16.0.2
Leaf2Ethernet 0/0 (Mc-Lag)100.0.10.201
Leaf2Ethernet 0/4(peer-link)11.0.0.12
Leaf2Ethernet 0/4810.0.11.1
Leaf2Loopback 0 172.16.0.3
Leaf3Ethernet 0/0 100.0.20.201
Leaf3Ethernet 0/4810.0.12.1
Leaf3Loopback 0 172.16.0.4
Server-1Bond0100.0.10.200
Server-2Eth0100.0.20.200

5.4 测试前的准备工作

确保各设备按照拓扑图正确连接,确保iperf3测试软件正确安装。

5.5 配置步骤

第 1 步

配置 server1 的 bond0 接口的 IP 地址和网关。

[admin@Server1~]# sudo vim /etc/sysconfig/network-scripts/ifcfg-bond0
DEVICE=bond0
BOOTPROTO=none
BROADCAST=100.0.10.255
IPADDR=100.0.10.200
NETMASK=255.255.255.0
NETWORK=100.0.10.0
ONBOOT=yes
USERCTL=no
GATEWAY=100.0.10.201
BONDING_OPTS=”miimon=100 mode=4 lacp_rate=fast xmit_hash_policy=layer2+3 fail_over_mac=1″
MASTER=yes
[admin@Server1~]# sudo vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=”eth0″
BOOTPROTO=none
ONBOOT=”yes”
MASTER=bond0
SLAVE=yes
HWADDR=”b8:59:9f:42:36:68″
[admin@Server1~]# sudo vim /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=”eth1″
BOOTPROTO=none
ONBOOT=”yes”
MASTER=bond0
SLAVE=yes
HWADDR=”b8:59:9f:42:36:69″
[admin@Server1~]# sudo systemctl restart network

第 2 步

配置 server2 的 eth0 接口的 IP 地址和网关。

[admin@Server1~]# sudo ifconfig eth0 100.0.20.200/24 up
[admin@Server1~]# sudo route add default gw 100.0.20.201

第 3 步

配置spine switch IP地址。

sonic# configure terminal
sonic(config)# interface ethernet 0/0
sonic(config-if-0/0)# ip address 10.0.10.201/24
sonic(config-if-0/0)# interface ethernet 0/4
sonic(config-if-0/4)# ip address 10.0.11.201/24
sonic(config-if-0/4)# interface ethernet 0/8
sonic(config-if-0/8)# ip address 10.0.12.201/24
sonic(config-if-0/8)# exit
sonic(config)# interface loopback 0
sonic(config-loif-0)# ip address 172.16.0.1/32

第 4 步

配置三台leaf设备的IP 地址和 MC-LAG。

Leaf1 配置

sonic# configure terminal
sonic(config)# interface ethernet 0/48
sonic(config-if-0/48)# ip address 10.0.10.1/24
sonic(config-if-0/48)# interface loopback 0
sonic(config-loif-0)# ip address 172.16.0.2/32
sonic(config-loif-0)# exit
sonic(config)# vlan 10
sonic(config-vlan-10)# exit
sonic(config)# vlan 30
sonic(config-vlan-30)# exit
sonic(config)# interface link-aggregation 10
sonic(config-lagif-10)# exit
sonic(config)# interface ethernet 0/0
sonic(config-if-0/0)# speed 10000
sonic(config-if-0/0)# link-aggregation-group 10
sonic(config-if-0/0)# exit
sonic(config)# interface ethernet 0/4
sonic(config-if-0/4)# speed 10000
sonic(config-if-0/4)# switchport trunk vlan 10
sonic(config-if-0/4)# switchport trunk vlan 30
sonic(config-if-0/4)# exit
sonic(config)# interface link-aggregation 10
sonic(config-lagif-10)# switchport trunk vlan 10
sonic(config-lagif-10)# exit
sonic(config)# vlan 10
sonic(config-vlan-10)# ip address 100.0.10.201/24
sonic(config-vlan-10)# exit
sonic(config)# vlan 30
sonic(config-vlan-30)# ip address 11.0.0.11/24
sonic(config-vlan-10)# exit
sonic(config)# monitor-link-group monitor1
sonic(config)# interface ethernet 0/48
sonic(config-if-0/48)# monitor-link monitor1 uplink
sonic(config-if-0/48)# exit
sonic(config)# interface ethernet 0/0
sonic(config-if-0/0)# monitor-link monitor1 downlink
sonic(config-if-0/0)# exit
sonic(config)# mclag domain 10
sonic(mclag-domain)# peer-link ethernet 0/4
sonic(mclag-domain)# local-address 11.0.0.11
sonic(mclag-domain)# peer-address 11.0.0.12
sonic(mclag-domain)# member lag 10
sonic(mclag-domain)# commit
sonic(mclag-domain)# interface vlan 10
sonic(config-vlan-10)# mac-address 00:11:22:33:44:55
sonic(config-vlan-10)# exit
sonic(config)# write

Leaf2 配置

sonic# configure terminal
sonic(config)# interface ethernet 0/48
sonic(config-if-0/48)# ip address 10.0.11.1/24
sonic(config-if-0/48)# interface loopback 0
sonic(config-loif-0)# ip address 172.16.0.3/32
sonic(config-loif-0)# exit
sonic(config)# vlan 10
sonic(config-vlan-10)# exit
sonic(config)# vlan 30
sonic(config-vlan-30)# exit
sonic(config)# interface link-aggregation 10
sonic(config-lagif-10)# exit
sonic(config)# interface ethernet 0/0
sonic(config-if-0/0)# speed 10000
sonic(config-if-0/0)# link-aggregation-group 10
sonic(config-if-0/0)# exit
sonic(config)# interface ethernet 0/4
sonic(config-if-0/4)# speed 10000
sonic(config-if-0/4)# switchport trunk vlan 10
sonic(config-if-0/4)# switchport trunk vlan 30
sonic(config-if-0/4)# exit
sonic(config)# interface link-aggregation 10
sonic(config-lagif-10)# switchport trunk vlan 10
sonic(config-lagif-10)# exit
sonic(config)# vlan 10
sonic(config-vlan-10)# ip address 100.0.10.201/24
sonic(config-vlan-10)# exit
sonic(config)# vlan 30
sonic(config-vlan-30)# ip address 11.0.0.12/24
sonic(config-vlan-10)# exit
sonic(config)# monitor-link-group monitor1
sonic(config)# interface ethernet 0/48
sonic(config-if-0/48)# monitor-link monitor1 uplink
sonic(config-if-0/48)# exit
sonic(config)# interface ethernet 0/0
sonic(config-if-0/0)# monitor-link monitor1 downlink
sonic(config-if-0/0)# exit
sonic(config)# mclag domain 10
sonic(mclag-domain)# peer-link ethernet 0/4
sonic(mclag-domain)# local-address 11.0.0.12
sonic(mclag-domain)# peer-address 11.0.0.11
sonic(mclag-domain)# member lag 10
sonic(mclag-domain)# commit
sonic(mclag-domain)# interface vlan 10
sonic(config-vlan-10)# mac-address 00:11:22:33:44:55
sonic(config-vlan-10)# exit
sonic(config)# write

Leaf3 配置

sonic# configure terminal
sonic(config)# interface ethernet 0/48
sonic(config-if-0/48)# ip address 10.0.12.1/24
sonic(config-if-0/48)# interface ethernet 0/0
sonic(config-if-0/0)# speed 10000
sonic(config-if-0/0)# ip address 100.0.20.201/24
sonic(config-if-0/0)# interface loopback 0
sonic(config-loif-0)# ip address 172.16.0.4/32
sonic(config-loif-0)# exit
sonic(config)# write

第 5 步

配置spine设备bgp。

sonic# configure terminal
sonic(config)# router bgp 65001
sonic(config-router)# bgp router-id 171.16.0.1
sonic(config-router)# no bgp ebgp-requires-policy
sonic(config-router)# neighbor 172.16.0.2 remote-as 65002
sonic(config-router)# neighbor 172.16.0.3 remote-as 65002
sonic(config-router)# neighbor 172.16.0.4 remote-as 65004
sonic(config-router)# address-family l2vpn evpn
sonic(config-router)# neighbor 172.16.0.2 activate
sonic(config-router)# neighbor 172.16.0.3 activate
sonic(config-router)# neighbor 172.16.0.4 activate
sonic(config-router)# advertise-all-vni
sonic(config)# write
sonic(config)# reload

第 6 步

 配置三台leaf设备bgp。

Leaf1 配置

sonic(config)# router bgp 65002
sonic(config-router)# bgp router-id 171.16.0.2
sonic(config-router)# no bgp ebgp-requires-policy
sonic(config-router)# neighbor 172.16.0.1 remote-as 65001
sonic(config-router)# neighbor 172.16.0.3 remote-as 65002
sonic(config-router)# address-family ipv4 unicast
sonic(config-router-af)# network 172.16.0.2/32
sonic(config-router-af)# exit
sonic(config)# router bgp 65002
sonic(config-router)# address-family l2vpn evpn
sonic(config-router)# neighbor 172.16.0.1 activate
sonic(config-router)# neighbor 172.16.0.3 activate
sonic(config-router)# advertise-all-vni
sonic(config)# write
sonic(config)# reload

Leaf2 配置

sonic(config)# router bgp 65002
sonic(config-router)# bgp router-id 171.16.0.3
sonic(config-router)# no bgp ebgp-requires-policy
sonic(config-router)# neighbor 172.16.0.1 remote-as 65001
sonic(config-router)# neighbor 172.16.0.2 remote-as 65002
sonic(config-router)# address-family ipv4 unicast
sonic(config-router-af)# network 172.16.0.3/32
sonic(config-router-af)# exit
sonic(config)# router bgp 65002
sonic(config-router)# address-family l2vpn evpn
sonic(config-router)# neighbor 172.16.0.1 activate
sonic(config-router)# neighbor 172.16.0.2 activate
sonic(config-router)# advertise-all-vni
sonic(config)# write
sonic(config)# reload

Leaf3 配置

sonic(config)# router bgp 65004
sonic(config-router)# bgp router-id 171.16.0.4
sonic(config-router)# no bgp ebgp-requires-policy
sonic(config-router)# neighbor 172.16.0.1 remote-as 65001
sonic(config-router)# address-family ipv4 unicast
sonic(config-router-af)# network 172.16.0.4/32
sonic(config-router-af)# exit
sonic(config)# router bgp 65004
sonic(config-router)# address-family l2vpn evpn
sonic(config-router)# neighbor 172.16.0.1 activate
sonic(config-router)# advertise-all-vni
sonic(config)# write
sonic(config)# reload

第 7 步

用server1发送流量到server2,并查看spine上流量走向

[admin@Server2~]# iperf3 -s
[admin@Server1~]# iperf3 -c 100.0.20.200 -l 20k -b 100G -M 9000 -t 1000

查看Spine设备流量

查看Spine设备流量

第 8 步

将leaf1上行接口0/48 down,查看spine流量走向

查看spine流量走向

6 结论

本次测试中,mc-lag链路故障后服务器之间可以正常通信,mc-lag链路恢复后服务器之间仍然可以正常通信,说明通过两台asterfusion sonic switch组成的mc-lag网络可以满足用户对网络高稳定性及高可靠性的需求。

点击了解Asterfusion CX-N数据中心交换机

如有其它问题,请填写右侧需求表单联系我们

配置指导:vAsterNOS(设备模拟器)上的EVPN Multi-homing场景配置

1 目的

本文主要介绍EVPN Multihoming场景在Asterfusion虚拟SONiC交换机(vAsterNOS)上的配置实现。通过阅读本文,用户可以快速理解和掌握EVPN Multihoming在Asterfusion SONiC交换机上的配置方法。

2 简介

2.1 vAsterNOS

vAsterNos是星融元推出的一款sonic交换机的虚拟操作系统,它继承了AsterNOS的所有软件特性,可运行在GNS3、EVE-NG等网络虚拟软件中。用户可以通过使用vAsterNos更好地了解星融元企业级sonic交换机的特性,从而为构建高效网络环境提供有力支撑。

关于设置vAsterNOS的使用环境的信息,请阅读:
Asterfusion虚拟SONiC交换机使用说明

2.2 EVPN Multihoming

EVPN Multihoming是指在使用以太网VPN(Ethernet VPN,EVPN)技术构建的数据中心网络中,使用多个物理链路和IP地址来实现冗余和负载均衡的技术。在EVPN Multihoming中,每个用户可以使用多个物理链路来与数据中心网络进行连接,这些链路可以来自不同的交换机。当一个链路或设备发生故障时,可以自动切换到备用链路或设备,保证数据中心网络的可用性。也可以通过负载均衡的方式,将网络流量分配到多个链路或地址中,提高网络性能和效率。Multihoming技术标准可参照RFC7432 and RFC4116,其具有良好的兼容性。

2.3 ESI

ESl(Ethernet Segmentldentifier,以太网段标识),用于标识 ES(Ethernet Segment),长度为 10 字节。
当前支持两种方式配置 ES1:
(1)配置唯一10 字节的 ESI、格式为 00:AA:BB:CC:DD:EE:FF:GG:HH:II;

(2)配置 es-id 和 es-sys-mac,再与保留位组成唯一 10 字节的 ESI。

使用时,为一组Leaf 设备连接到同一用户侧设备或主机的下行聚合口配置相同的 ESI,则这两个聚合口互为EVPN-Multihoming 对等体,该聚合接口也称为 ES 接口,该 Leaf 交换机也称为 ES 设备。

2.4 DF设备

在一组 ES 设备上,会为每个 ES 选择一个指定转发器,被选中的交换机称为DF(Designated Forwarder)设备,相应的,没有被选举成为DF的则称为 Non-DF设备。只有DF设备才允许将VXLAN 隧道收到的泛洪流量转发到本地配置 ESI的下行口,Non-DF设备则不允许。

3 技术原理

3.1 对等体发现

与 MC-LAG不同,EVPN-Multihoming 对等体之间无需 peer-link 互通,而是通过 EVPNtype-4路由(EthernetSegment Route)和type-1路由(Ethernet Auto-Discovery Route)进行动态发现。

EVPN-Multihoming 对等体节点通过配置相同的 ESI 进行互通、作为独立的 VTEP,具有唯一的 VTEP IP 地址

3.2 DF选举算法

DF 选举算法用于解决远端 BUM 流量复制问题:只有 DF 设备才允许将 VXLAN 隧道收到的泛洪流量转发到本地配置 ESI的下行口,Non-DF 设备则不允许。

在同一个 ES 中,具有最高 DF 偏好的 VTEP节点将成为 DF 设备,若偏好值相同,则选举具有最小 VTEPIP 地址的成为 DF 设备。DF选举动作由 EVPN type-4路由完成。

3.3 水平分割算法

水平分割算法用于防止同一个 ESI的 BUM 流量环路和复制:只有来自远程站点的 BUM 流量才被允许转发到本地站点。

4 EVPN Multihoming典型场景配置

4.1 要求

用户的数据中心拥有一套2+4的spine-leaf网络,现在需要将3台server部署在此网络中,要求使用multihoming部署方式,保障网络的高可靠性。具体组网情况参见4.2章网络拓扑。

4.2 拓扑

网络拓扑

4.3 测试环境

此配置示例采用 Asterfusion 虚拟 SONiC 交换机 (vAsterNOS) 实现,因此需要运行 vAsterNOS 的虚拟环境。具体环境搭建请参考本文2.1节的相关链接。

4.4 设备互联IP

设备名称接口IP地址备注
Spine1Ethernet 0/0 172.16.11.1/24
Spine1Ethernet 0/1172.16.12.1/24
Spine1Ethernet 0/2172.16.13.1/24
Spine1Ethernet 0/3172.16.14.1/24Router-id same as loopback0
Spine1Loopback 0 10.1.0.210/32
Spine2Ethernet 0/0 172.16.15.1/24
Spine2Ethernet 0/1172.16.16.1/24
Spine2Ethernet 0/2172.16.17.1/24
Spine2Ethernet 0/3172.16.18.1/24
Spine2Loopback 0 10.1.0.211/32Router-id same as loopback0
Leaf1Ethernet 0/2172.16.11.2/24
Leaf1Ethernet 0/3172.16.15.2/24
Leaf1Vlan 100100.0.0.1/24
Leaf1Vlan 200110.0.0.1/24
Leaf1Loopback 0 10.1.0.212/32Router-id and vtep ip same as loopback0
Leaf2Ethernet 0/2172.16.12.2/24
Leaf2Ethernet 0/3172.16.16.2/24
Leaf2Vlan 100100.0.0.1/24
Leaf2Vlan 200110.0.0.1/24
Leaf2Loopback 0 10.1.0.213/32Router-id and vtep ip same as loopback0
Leaf3Ethernet 0/1172.16.13.2/24
Leaf3Ethernet 0/2172.16.17.2/24
Leaf3Vlan 300120.0.0.1/24
Leaf3Loopback 0 10.1.0.214/32Router-id and vtep-ip same as loopback0
Leaf4Ethernet 0/1172.16.14.2/24
Leaf4Ethernet 0/2172.16.18.2/24
Leaf4Vlan 300120.0.0.1/24
Leaf4Loopback 0 10.1.0.215/32Router-id and vtep-ip same as loopback0
Server-1bond0100.0.0.12/24

4.5 测试前的准备工作

确保各switch及server设备正确上线,并按照拓扑正确连接。

确保设备正确上线

4.6 配置步骤

第 1 步

修改6台switches设备的mac地址,由于初始mac地址相同,所以在进行业务配置之前,必须先进行mac地址的修改。才能使设备功能正常运行。

sonic# system bash
admin@sonic:~$ sudo vi /etc/sonic/config_db.json

修改如下位置

修改位置

重新加载配置并退出system bash。

admin@sonic:~$ sudo config reload -yf
admin@sonic:~$ exit

第 2 步

配置各交换机设备的互联端口。

Spine1

sonic# configure terminal
sonic(config)# interface ethernet 0/1
sonic(config-if-0/1)# ip address 172.16.11.1/24
sonic(config-if-0/1)# interface ethernet 0/2
sonic(config-if-0/2)# ip address 172.16.12.1/24
sonic(config-if-0/2)# interface ethernet 0/3
sonic(config-if-0/3)# ip address 172.16.13.1/24
sonic(config-if-0/3)# interface ethernet 0/4
sonic(config-if-0/4)# ip address 172.16.14.1/24
sonic(config-if-0/4)# exit
sonic(config)# interface loopback 0
sonic(config-loif-0)# ip address 10.1.0.210/32
sonic(config-loif-0)#exit

Spine2

sonic# configure terminal
sonic(config)# interface ethernet 0/1
sonic(config-if-0/1)# ip address 172.16.15.1/24
sonic(config-if-0/1)# interface ethernet 0/2
sonic(config-if-0/2)# ip address 172.16.16.1/24
sonic(config-if-0/2)# interface ethernet 0/3
sonic(config-if-0/3)# ip address 172.16.17.1/24
sonic(config-if-0/3)# interface ethernet 0/4
sonic(config-if-0/4)# ip address 172.16.18.1/24
sonic(config-if-0/4)# q
sonic(config)# interface loopback 0
sonic(config-loif-0)# ip address 10.1.0.211/32
sonic(config-loif-0)#exit

Leaf1

sonic# configure terminal
sonic(config)# interface ethernet 0/3
sonic(config-if-0/3)# ip address 172.16.11.2/24
sonic(config-if-0/3)# interface ethernet 0/4
sonic(config-if-0/4)# ip address 172.16.15.2/24
sonic(config-if-0/4)# exit
sonic(config)# interface loopback 0
sonic(config-loif-0)# ip address 10.1.0.212/32

Leaf2

sonic# configure terminal
sonic(config)# interface ethernet 0/3
sonic(config-if-0/3)# ip address 172.16.12.2/24
sonic(config-if-0/3)# interface ethernet 0/4
sonic(config-if-0/4)# ip address 172.16.16.2/24
sonic(config-if-0/4)# exit
sonic(config)# interface loopback 0
sonic(config-loif-0)# ip address 10.1.0.213/32

Leaf3

sonic# configure terminal
sonic(config)# interface ethernet 0/2
sonic(config-if-0/2)# ip address 172.16.13.2/24
sonic(config-if-0/2)# interface ethernet 0/3
sonic(config-if-0/3)# ip address 172.16.17.2/24
sonic(config-if-0/3)# exit
sonic(config)# interface loopback 0
sonic(config-loif-0)# ip address 10.1.0.214/32

Leaf4

sonic# configure terminal
sonic(config)# interface ethernet 0/2
sonic(config-if-0/2)# ip address 172.16.14.2/24
sonic(config-if-0/2)# interface ethernet 0/3
sonic(config-if-0/3)# ip address 172.16.18.2/24
sonic(config-if-0/3)# exit
sonic(config)# interface loopback 0
sonic(config-loif-0)# ip address 10.1.0.215/32

第 3 步

配置Leaf设备的聚合口

Leaf1

sonic(config)# interface link-aggregation 5
sonic(config-lagif-5)# exit
sonic(config)# interface ethernet 0/1
sonic(config-if-0/1)# switchport
sonic(config-if-0/1)# link-aggregation-group 5
sonic(config-if-0/1)# exit
sonic(config)# interface link-aggregation 6
sonic(config-lagif-6)# exit
sonic(config)# interface ethernet 0/2
sonic(config-if-0/2)# switchport
sonic(config-if-0/2)# link-aggregation-group 6
sonic(config-if-0/2)# exit
sonic(config)# vlan 100
sonic(config-vlan-100)# vlan 200
sonic(config-vlan-200)# exit
sonic(config)# interface link-aggregation 5
sonic(config-lagif-5)# switchport access vlan 100
sonic(config-lagif-5)# lacp system-id 00:00:01:00:00:01
sonic(config-lagif-5)# exit
sonic(config)# interface link-aggregation 6
sonic(config-lagif-6)# switchport access vlan 200
sonic(config-lagif-6)# lacp system-id 00:00:01:00:00:02
sonic(config-lagif-6)# exit
sonic(config)# vrf 123
sonic(config-vrf)# exit
sonic(config)# interface vlan 100
sonic(config-vlanif-100)# ip address 100.0.0.1/24
sonic(config-vlanif-100)# mac-address 00:11:22:33:44:55
sonic(config-vlanif-100)# vrf 123
sonic(config-vlanif-100)# interface vlan 200
sonic(config-vlanif-200)# ip address 110.0.0.1/24
sonic(config-vlanif-200)# mac-address 00:11:22:33:44:66
sonic(config-vlanif-200)# vrf 123
sonic(config-vlanif-200)# exit

Leaf2

sonic(config)# interface link-aggregation 5
sonic(config-lagif-5)# exit
sonic(config)# interface ethernet 0/1
sonic(config-if-0/1)# switchport
sonic(config-if-0/1)# link-aggregation-group 5
sonic(config-if-0/1)# exit
sonic(config)# interface link-aggregation 6
sonic(config-lagif-6)# exit
sonic(config)# interface ethernet 0/2
sonic(config-if-0/2)# switchport
sonic(config-if-0/2)# link-aggregation-group 6
sonic(config-if-0/2)# exit
sonic(config)# vlan 100
sonic(config-vlan-100)# vlan 200
sonic(config-vlan-200)# exit
sonic(config)# interface link-aggregation 5
sonic(config-lagif-5)# switchport access vlan 100
sonic(config-lagif-5)# lacp system-id 00:00:01:00:00:01
sonic(config-lagif-5)# exit
sonic(config)# interface link-aggregation 6
sonic(config-lagif-6)# switchport access vlan 200
sonic(config-lagif-6)# lacp system-id 00:00:01:00:00:02
sonic(config-lagif-6)# exit
sonic(config)# vrf 123
sonic(config-vrf)# exit
sonic(config)# interface vlan 100
sonic(config-vlanif-100)# ip address 100.0.0.1/24
sonic(config-vlanif-100)# mac-address 00:11:22:33:44:55
sonic(config-vlanif-100)# vrf 123
sonic(config-vlanif-100)# interface vlan 200
sonic(config-vlanif-200)# ip address 110.0.0.1/24
sonic(config-vlanif-200)# mac-address 00:11:22:33:44:66
sonic(config-vlanif-200)# vrf 123
sonic(config-vlanif-200)# exit

Leaf3

sonic(config)# interface link-aggregation 7
sonic(config-lagif-7)# exit
sonic(config)# interface ethernet 0/1
sonic(config-if-0/1)# switchport
sonic(config-if-0/1)# link-aggregation-group 7
sonic(config-if-0/1)# exit
sonic(config)# vlan 300
sonic(config-vlan-300)# exit
sonic(config)# interface link-aggregation 7
sonic(config-lagif-7)# switchport access vlan 300
sonic(config-lagif-7)# lacp system-id 00:00:01:00:00:03
sonic(config-lagif-7)# exit
sonic(config)# vrf 456
sonic(config-vrf)# exit
sonic(config)# interface vlan 300
sonic(config-vlanif-300)# ip address 120.0.0.1/24
sonic(config-vlanif-300)# mac-address 00:11:22:33:44:77
sonic(config-vlanif-300)# vrf 456
sonic(config-vlanif-300)# exit

Leaf4

sonic(config)# interface link-aggregation 7
sonic(config-lagif-7)# exit
sonic(config)# interface ethernet 0/1
sonic(config-if-0/1)# switchport
sonic(config-if-0/1)# link-aggregation-group 7
sonic(config-if-0/1)# exit
sonic(config)# vlan 300
sonic(config-vlan-300)# exit
sonic(config)# interface link-aggregation 7
sonic(config-lagif-7)# switchport access vlan 300
sonic(config-lagif-7)# lacp system-id 00:00:01:00:00:03
sonic(config-lagif-7)# exit
sonic(config)# vrf 456
sonic(config-vrf)# exit
sonic(config)# interface vlan 300
sonic(config-vlanif-300)# ip address 120.0.0.1/24
sonic(config-vlanif-300)# mac-address 00:11:22:33:44:77
sonic(config-vlanif-300)# vrf 456
sonic(config-vlanif-300)# exit

第 4 步

配置 BGP

Spine1

sonic(config)# router bgp 65200
sonic(config-router)# bgp router-id 10.1.0.210
sonic(config-router)# no bgp ebgp-requires-policy
sonic(config-router)# neighbor PEER_V4_EBGP peer-group
sonic(config-router)# neighbor 172.16.11.2 remote-as 65202
sonic(config-router)# neighbor 172.16.11.2 peer-group PEER_V4_EBGP
sonic(config-router)# neighbor 172.16.12.2 remote-as 65203
sonic(config-router)# neighbor 172.16.12.2 peer-group PEER_V4_EBGP
sonic(config-router)# neighbor 172.16.13.2 remote-as 65204
sonic(config-router)# neighbor 172.16.13.2 peer-group PEER_V4_EBGP
sonic(config-router)# neighbor 172.16.14.2 remote-as 65205
sonic(config-router)# neighbor 172.16.14.2 peer-group PEER_V4_EBGP
sonic(config-router)# address-family ipv4 unicast
sonic(config-router-af)# network 10.1.0.210/32
sonic(config-router-af)# neighbor PEER_V4_EBGP activate
sonic(config-router-af)# redistribute connected
sonic(config-router-af)#exit
sonic(config-router)# address-family l2vpn evpn
sonic(config-router-af)# advertise-all-vni
sonic(config-router-af)# neighbor PEER_V4_EBGP activate
sonic(config-router-af)#end
sonic#write
sonic#reload

Spine2

sonic(config)# router bgp 65201
sonic(config-router)# bgp router-id 10.1.0.211
sonic(config-router)# no bgp ebgp-requires-policy
sonic(config-router)# neighbor PEER_V4_EBGP peer-group
sonic(config-router)# neighbor 172.16.15.2 remote-as 65202
sonic(config-router)# neighbor 172.16.15.2 peer-group PEER_V4_EBGP
sonic(config-router)# neighbor 172.16.16.2 remote-as 65203
sonic(config-router)# neighbor 172.16.16.2 peer-group PEER_V4_EBGP
sonic(config-router)# neighbor 172.16.17.2 remote-as 65204
sonic(config-router)# neighbor 172.16.17.2 peer-group PEER_V4_EBGP
sonic(config-router)# neighbor 172.16.18.2 remote-as 65205
sonic(config-router)# neighbor 172.16.18.2 peer-group PEER_V4_EBGP
sonic(config-router)# address-family ipv4 unicast
sonic(config-router-af)# network 10.1.0.211/32
sonic(config-router-af)# neighbor PEER_V4_EBGP activate
sonic(config-router-af)# redistribute connected
sonic(config-router-af)#exit
sonic(config-router)# address-family l2vpn evpn
sonic(config-router-af)# advertise-all-vni
sonic(config-router-af)# neighbor PEER_V4_EBGP activate
sonic(config-router-af)#end
sonic# write
sonic# reload

Leaf1 

sonic(config)# router bgp 65202
sonic(config-router)# bgp router-id 10.1.0.212
sonic(config-router)# no bgp ebgp-requires-policy
sonic(config-router)# neighbor PEER_V4_EBGP peer-group
sonic(config-router)# neighbor 172.16.11.1 remote-as 65200
sonic(config-router)# neighbor 172.16.11.1 peer-group PEER_V4_EBGP
sonic(config-router)# neighbor 172.16.15.1 remote-as 65201
sonic(config-router)# neighbor 172.16.15.1 peer-group PEER_V4_EBGP
sonic(config-router)# address-family ipv4 unicast
sonic(config-router-af)# network 10.1.0.212/32
sonic(config-router-af)# neighbor PEER_V4_EBGP activate
sonic(config-router-af)# redistribute connected
sonic(config-router-af)# exit
sonic(config-router)# address-family l2vpn evpn
sonic(config-router-af)# advertise-all-vni
sonic(config-router-af)# neighbor PEER_V4_EBGP activate
sonic(config-router-af)#exit
sonic(config-router)#exit

Leaf2

sonic(config)# router bgp 65203
sonic(config-router)# bgp router-id 10.1.0.213
sonic(config-router)# no bgp ebgp-requires-policy
sonic(config-router)# neighbor PEER_V4_EBGP peer-group
sonic(config-router)# neighbor 172.16.12.1 remote-as 65200
sonic(config-router)# neighbor 172.16.12.1 peer-group PEER_V4_EBGP
sonic(config-router)# neighbor 172.16.16.1 remote-as 65201
sonic(config-router)# neighbor 172.16.16.1 peer-group PEER_V4_EBGP
sonic(config-router)# address-family ipv4 unicast
sonic(config-router-af)# network 10.1.0.213/32
sonic(config-router-af)# neighbor PEER_V4_EBGP activate
sonic(config-router-af)# redistribute connected
sonic(config-router-af)# exit
sonic(config-router)# address-family l2vpn evpn
sonic(config-router-af)# advertise-all-vni
sonic(config-router-af)# neighbor PEER_V4_EBGP activate
sonic(config-router-af)#exit
sonic(config-router)#exit

Leaf3

sonic(config)# router bgp 65204
sonic(config-router)# bgp router-id 10.1.0.214
sonic(config-router)# no bgp ebgp-requires-policy
sonic(config-router)# neighbor PEER_V4_EBGP peer-group
sonic(config-router)# neighbor 172.16.13.1 remote-as 65200
sonic(config-router)# neighbor 172.16.13.1 peer-group PEER_V4_EBGP
sonic(config-router)# neighbor 172.16.17.1 remote-as 65201
sonic(config-router)# neighbor 172.16.17.1 peer-group PEER_V4_EBGP
sonic(config-router)# address-family ipv4 unicast
sonic(config-router-af)# network 10.1.0.214/32
sonic(config-router-af)# neighbor PEER_V4_EBGP activate
sonic(config-router-af)# redistribute connected
sonic(config-router-af)# exit
sonic(config-router)# address-family l2vpn evpn
sonic(config-router-af)# advertise-all-vni
sonic(config-router-af)# neighbor PEER_V4_EBGP activate
sonic(config-router-af)# exit
sonic(config-router)# exit

Leaf4

sonic(config)# router bgp 65205
sonic(config-router)# bgp router-id 10.1.0.215
sonic(config-router)# no bgp ebgp-requires-policy
sonic(config-router)# neighbor PEER_V4_EBGP peer-group
sonic(config-router)# neighbor 172.16.14.1 remote-as 65200
sonic(config-router)# neighbor 172.16.14.1 peer-group PEER_V4_EBGP
sonic(config-router)# neighbor 172.16.18.1 remote-as 65201
sonic(config-router)# neighbor 172.16.18.1 peer-group PEER_V4_EBGP
sonic(config-router)# address-family ipv4 unicast
sonic(config-router-af)# network 10.1.0.215/32
sonic(config-router-af)# neighbor PEER_V4_EBGP activate
sonic(config-router-af)# redistribute connected
sonic(config-router-af)# exit
sonic(config-router)# address-family l2vpn evpn
sonic(config-router-af)# advertise-all-vni
sonic(config-router-af)# neighbor PEER_V4_EBGP activate
sonic(config-router-af)# exit
sonic(config-router)# exit

第 5 步

配置evpn multihoming

Leaf1

sonic(config)# interface vxlan 0
sonic(config-vxlanif-0)# source 10.1.0.212
sonic(config-vxlanif-0)# exit
sonic(config)# vlan 100
sonic (config-vlan-100)# vni 100
sonic (config-vlan-100)# exit
sonic(config)# vlan 200
sonic (config-vlan-200)# vni 200
sonic (config-vlan-200)# exit
sonic(config)# vrf 123
sonic(config-vrf)# vni 1000
sonic(config-vrf)# exit
sonic(config)# evpn mh redirect-off
sonic(config)# evpn mh mac-holdtime 0
sonic(config)# evpn mh neigh-holdtime 0
sonic(config)# interface ethernet 0/3
sonic(config-if-0/3)# evpn mh uplink
sonic(config-if-0/3)# exit
sonic(config)# interface ethernet 0/4
sonic(config-if-0/4)# evpn mh uplink
sonic(config-if-0/4)# exit
sonic(config)# interface link-aggregation 5
sonic(config-lagif-5)# evpn mh es-id 100
sonic(config-lagif-5)# evpn mh es-sys-mac 00:00:01:00:00:01
sonic(config-lagif-5)# interface link-aggregation 6
sonic(config-lagif-6)# evpn mh es-id 200
sonic(config-lagif-6)# evpn mh es-sys-mac 00:00:01:00:00:02
sonic(config-lagif-6)#end
sonic# write
sonic# reload

Leaf2

sonic(config)# interface vxlan 0
sonic(config-vxlanif-0)# source 10.1.0.213
sonic(config-vxlanif-0)# exit
sonic(config)# vlan 100
sonic (config-vlan-100)# vni 100
sonic (config-vlan-100)# exit
sonic(config)# vlan 200
sonic (config-vlan-200)# vni 200
sonic (config-vlan-200)# exit
sonic(config)# vrf 123
sonic(config-vrf)# vni 1000
sonic(config-vrf)# exit
sonic(config)# evpn mh redirect-off
sonic(config)# evpn mh mac-holdtime 0
sonic(config)# evpn mh neigh-holdtime 0
sonic(config)# interface ethernet 0/3
sonic(config-if-0/3)# evpn mh uplink
sonic(config-if-0/3)# exit
sonic(config)# interface ethernet 0/4
sonic(config-if-0/4)# evpn mh uplink
sonic(config-if-0/4)# exit
sonic(config)# interface link-aggregation 5
sonic(config-lagif-5)# evpn mh es-id 100
sonic(config-lagif-5)# evpn mh es-sys-mac 00:00:01:00:00:01
sonic(config-lagif-5)# interface link-aggregation 6
sonic(config-lagif-6)# evpn mh es-id 200
sonic(config-lagif-6)# evpn mh es-sys-mac 00:00:01:00:00:02
sonic(config-lagif-6)#end
sonic# write
sonic# reload

Leaf3

sonic(config)# interface vxlan 0
sonic(config-vxlanif-0)# source 10.1.0.214
sonic(config-vxlanif-0)# exit
sonic(config)# vlan 300
sonic (config-vlan-300)# vni 300
sonic (config-vlan-300)# exit
sonic(config)# vrf 456
sonic(config-vrf)# vni 1000
sonic(config-vrf)# exit
sonic(config)# evpn mh redirect-off
sonic(config)# evpn mh mac-holdtime 0
sonic(config)# evpn mh neigh-holdtime 0
sonic(config)# interface ethernet 0/2
sonic(config-if-0/2)# evpn mh uplink
sonic(config-if-0/2)# exit
sonic(config)# interface ethernet 0/3
sonic(config-if-0/3)# evpn mh uplink
sonic(config-if-0/3)# exit
sonic(config)# interface link-aggregation 7
sonic(config-lagif-7)# evpn mh es-id 300
sonic(config-lagif-7)# evpn mh es-sys-mac 00:00:01:00:00:03
sonic(config-lagif-7)#end
sonic# write
sonic# reload

Leaf4

sonic(config)# interface vxlan 0
sonic(config-vxlanif-0)# source 10.1.0.215
sonic(config-vxlanif-0)# exit
sonic(config)# vlan 300
sonic (config-vlan-300)# vni 300
sonic (config-vlan-300)# exit
sonic(config)# vrf 456
sonic(config-vrf)# vni 1000
sonic(config-vrf)# exit
sonic(config)# evpn mh redirect-off
sonic(config)# evpn mh mac-holdtime 0
sonic(config)# evpn mh neigh-holdtime 0
sonic(config)# interface ethernet 0/2
sonic(config-if-0/2)# evpn mh uplink
sonic(config-if-0/2)# exit
sonic(config)# interface ethernet 0/3
sonic(config-if-0/3)# evpn mh uplink
sonic(config-if-0/3)# exit
sonic(config)# interface link-aggregation 7
sonic(config-lagif-7)# evpn mh es-id 300
sonic(config-lagif-7)# evpn mh es-sys-mac 00:00:01:00:00:03
sonic(config-lagif-7)#end
sonic# write
sonic# reload

第 6 步

配置 3 台server的bond接口

Server-1

#configure bond0
[root@localhost /]# cd /etc/sysconfig/network-scripts/
[root@localhost network-scripts]# vi ifcfg-bond0
DEVICE=bond0
BOOTPROTO=static
TYPE=bond
ONBOOT=yes
BONDING_OPTS=”miimon=100 mode=4 lacp_rate=fast xmit_hash_policy=layer3+4 fail_over_mac=1 “
IPADDR=100.0.0.12
NETMASK=255.255.255.0
GATEWAY=100.0.0.1
MASTER=yes

#configure eth0
[root@localhost network-scripts]# vi ifcfg-eth0
DEVICE=”eth0″
BOOTPROTO=none
ONBOOT=”yes”
MASTER=bond0
SLAVE=yes

#configure eth1
[root@localhost network-scripts]# vi ifcfg-eth1
DEVICE=”eth1″
BOOTPROTO=none
ONBOOT=”yes”
MASTER=bond0
SLAVE=yes

Server-2

#configure bond0
[root@localhost /]# cd /etc/sysconfig/network-scripts/
[root@localhost network-scripts]# vi ifcfg-bond0
DEVICE=bond0
BOOTPROTO=static
TYPE=bond
ONBOOT=yes
BONDING_OPTS=”miimon=100 mode=4 lacp_rate=fast xmit_hash_policy=layer3+4 fail_over_mac=1 “
IPADDR=110.0.0.12
NETMASK=255.255.255.0
GATEWAY=110.0.0.1
MASTER=yes

#configure eth0
[root@localhost network-scripts]# vi ifcfg-eth0
DEVICE=”eth0″
BOOTPROTO=none
ONBOOT=”yes”
MASTER=bond0
SLAVE=yes

#configure eth1
[root@localhost network-scripts]# vi ifcfg-eth1
DEVICE=”eth1″
BOOTPROTO=none
ONBOOT=”yes”
MASTER=bond0
SLAVE=yes

Server-3

#configure bond0
[root@localhost /]# cd /etc/sysconfig/network-scripts/
[root@localhost network-scripts]# vi ifcfg-bond0
DEVICE=bond0
BOOTPROTO=static
TYPE=bond
ONBOOT=yes
BONDING_OPTS=”miimon=100 mode=4 lacp_rate=fast xmit_hash_policy=layer3+4 fail_over_mac=1 “
IPADDR=120.0.0.12
NETMASK=255.255.255.0
GATEWAY=120.0.0.1
MASTER=yes

#configure eth0
[root@localhost network-scripts]# vi ifcfg-eth0
DEVICE=”eth0″
BOOTPROTO=none
ONBOOT=”yes”
MASTER=bond0
SLAVE=yes

#configure eth1
[root@localhost network-scripts]# vi ifcfg-eth1
DEVICE=”eth1″
BOOTPROTO=none
ONBOOT=”yes”
MASTER=bond0
SLAVE=yes

完成配置后的server接口状态如下:

完成配置后的server接口状态

4.7 验证网络配置

1.各server之间互ping,能够ping通。

2.检查每个交换机的BGP状态。以 Spine1 和 Leaf1 为例:

Spine1

sonic# show bgp summary
Spine1 BGP状态

Leaf1

sonic# show bgp summary

Leaf1 BGP状态

从查询结果可以看出各switch的bgp状态正常。

3.查看各leaf的聚合口状态,以leaf1和leaf3为例:

Leaf1

sonic# show link-aggregation summary
Leaf1聚合口状态

Leaf3

sonic# show link-aggregation summary
Leaf3聚合口状态

从查询结果可以看出各leaf的lag口状态正常。

4.查看各leaf的vxlan隧道,以leaf1和leaf3为例

Leaf1

sonic# show vxlan tunnel
查看Leaf1 vxlan隧道

Leaf3

sonic# show vxlan tunnel
查看Leaf3 vxlan隧道

从查询结果可以看出各leaf vxlan tunnel状态正常。

5.查看各leaf的evpn multihoming 状态

Leaf1

sonic# show evpn es detail
查看leaf1的evpn multihoming 状态

Leaf2

sonic# show evpn es detail
查看leaf2的evpn multihoming 状态

Leaf3

sonic# show evpn es detail
查看leaf3的evpn multihoming 状态

Leaf4

sonic# show evpn es detail
查看各leaf4的evpn multihoming 状态

从查询结果可以看出4台leaf的状态正常,其中leaf1和leaf3分别作为DF设备。

6.用server1 ping server3,将leaf1的ethernet0/1接口down掉,查看lag5的DF设备状态,并查看server1的ping是否中断。

sonic(config-if-0/1)# shutdown
sonic# show evpn es detail
shutdown leaf1的ethernet0/1接口

从结果看,down掉0/1接口后,lag5的leaf1转变为non-df状态,同时leaf2转变为df状态。

并且Server1的ping没有中断。

5 结论

本次测试中,使用vAsterNOS及VM设备组网并配置EVPN Multihoming网络后,各VM之间能互相正常通信,并且leaf之间能正确建立vxlan隧道,相关路由也正常工作。当VM的其中一条接入链路断开后,数据会无缝切换到另一条链路继续传输,DF设备切换正常。当断开的链路重新连接正常后,DF设备也切回原来的设备,数据重新回到原来链路上传输。说明EVPN Multihoming功能工作正常,满足用户的网络高可靠需求。

6 设备升级

6.1 注意事项

以升级 Leaf-1 交换机为例,有以下注意事项:
(1)为减少 Leaf 设备升级期间对业务的影响,应当手动关闭 Leaf-1相应接口,将业务流量全部切换至 Leaf-2后,再对 Leaf-1 进行升级。
(2)如果在 Unique-IP VLAN 下有终端接入,若终端的网关设置为 Leaf-1 的 VLAN,需提前修改终端的网关为Leaf-2、再对 Leaf-1 进行升级。
(3)建议 Leaf 设备升级间隔至少 10 分钟。
下面对具体的操作步骤进行说明。

6.2 操作步骤

  • 登录 Leaf-1 交换机,完成待升级的镜像安装后,执行configure terminal命令,进入系统配置视图;
  • 将下行聚合接口的 LACP 协议状态依次置为 Down(该命令单次有效,重启自动恢复),实现用户侧流量的切换;
evpnmh-leaf-1(config)# interface link-aggregation 100 
evpnmh-leaf-1(config-lagif-100)# lacp graceful-down 
evpnmh-leaf-1(config)# interface link-aggregation 101 
evpnmh-leaf-1(config-lagif-100)# lacp graceful-down 

检查Leaf-1的下行聚合组状态:

evpnmh-leaf-1# show link-aggregation summary 
Flags: A - active, I - inactive, Up - up, Dw - Down, N/A - not available, 
       S - selected, D - deselected, * - not synced 
  No.  Team Dev         Protocol     Ports          Description -----  ---------------  -----------  -------------  ------------- 
 0100  lag 100          LACP(A)(Dw)  0/64      (D)  N/A 
  • 将上行口的物理状态依次置为 Down,实现隧道流量的切换
evpnmh-leaf-1(config)# interface ethernet 0/48 
evpnmh-leaf-1(config-if-0/48)# shutdown 
evpnmh-leaf-1(config-if-0/48)# interface ethernet 0/52 
evpnmh-leaf-1(config-if-0/52)# shutdown 
  • 通过show counters interface命令确定Leaf-1上没有流量经过,已完全切换至Leaf-2。
  • 升级重启Leaf-1;
 evpnmh-leaf-1# reboot 
Do you want to reboot? [y/N]: y 

待升级完成,流量将自动切回 Leaf-1,检査 Leaf-1 的下行聚合组状态、BGP 邻居状态是否正常,确认 Leaf-1 恢复转发流量,再按照同样步骤进行 Leaf-2 设备的升级。

点击了解Asterfusion CX-N数据中心交换机

如有其它问题,请填写右侧需求表单联系我们

对星融元产品感兴趣?

立即联系!

返回顶部

© 星融元数据技术(苏州)有限公司 苏ICP备17070048号-2