OpenStack Zun部署方案
1 目标与物理网络拓扑
本文主要描述在现有OpenStack(rocky版)平台上如何扩展安装Zun功能组件,实现容器管理服务。
涉及物理拓扑,如图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 |
2 硬件与软件环境
部署环境中涉及到的硬件和软件如表2和表3所示:
名称 | 型号 | 硬件指标 | 数量 | 备注 |
服务器 | 1.至少8G内存 2.磁盘不少于500G | 2 | Server-1计算节点+存储节点 Server-2 控制节点+网络节点 |
软件 | 版本 | 备注 |
操作系统 | Centos7.6 | 安装时选择Compute Node 模式,根目录/至少500G |
OpenStack | Rocky |
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 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