From a647e89c0aeb2ceca357a86ada01fff6170651e3 Mon Sep 17 00:00:00 2001 From: lauk001 Date: Fri, 2 Feb 2024 11:04:29 +0800 Subject: [PATCH] Improve the user manual --- cmd/deploy.go | 9 +++-- cmd/extend.go | 4 +-- cmd/template.go | 4 +-- docs/config_file_desc.md | 2 +- docs/globalconfig_file_desc.md | 8 +++++ docs/ignition_design.md | 33 +++++++++++++++++++ docs/manual.md | 31 ++++++++++++++--- pkg/cert/K8sCertKeyGenerator.go | 6 ++-- .../globalconfig/globalconfig.go | 3 +- test/httpserver_test/httpserver_test.go | 4 +-- 10 files changed, 82 insertions(+), 22 deletions(-) create mode 100644 docs/globalconfig_file_desc.md diff --git a/cmd/deploy.go b/cmd/deploy.go index ace4146..30a510e 100755 --- a/cmd/deploy.go +++ b/cmd/deploy.go @@ -18,7 +18,7 @@ package cmd import ( "context" "fmt" - "io/ioutil" + "io" "nestos-kubernetes-deployer/cmd/command" "nestos-kubernetes-deployer/cmd/command/opts" "nestos-kubernetes-deployer/data" @@ -395,15 +395,14 @@ func applyNetworkPlugin(pluginConfigPath string) error { return err } defer response.Body.Close() - - content, err = ioutil.ReadAll(response.Body) + content, err = io.ReadAll(response.Body) if err != nil { logrus.Errorf("Failed to read content from HTTP response: %v", err) return err } } else { // Read the content from the local file - content, err = ioutil.ReadFile(pluginConfigPath) + content, err = os.ReadFile(pluginConfigPath) if err != nil { logrus.Errorf("Failed to read network plugin configuration file: %v", err) return err @@ -423,7 +422,7 @@ func applyNetworkPlugin(pluginConfigPath string) error { // Save the modified content to a file in the "/tmp" directory with a fixed name tmpFilePath := "/tmp/modified-plugin-config.yaml" - err = ioutil.WriteFile(tmpFilePath, content, 0644) + err = os.WriteFile(tmpFilePath, content, 0644) if err != nil { logrus.Errorf("Failed to write content to file: %v", err) return err diff --git a/cmd/extend.go b/cmd/extend.go index 81d2915..d073710 100755 --- a/cmd/extend.go +++ b/cmd/extend.go @@ -18,7 +18,6 @@ package cmd import ( "context" "fmt" - "io/ioutil" "nestos-kubernetes-deployer/cmd/command" "nestos-kubernetes-deployer/cmd/command/opts" "nestos-kubernetes-deployer/pkg/configmanager" @@ -27,6 +26,7 @@ import ( "nestos-kubernetes-deployer/pkg/ignition/machine" "nestos-kubernetes-deployer/pkg/infra" "nestos-kubernetes-deployer/pkg/kubeclient" + "os" "time" "github.com/sirupsen/logrus" @@ -119,7 +119,7 @@ func extendArray(c *asset.ClusterAsset, count int) []string { } func extendCluster(conf *asset.ClusterAsset, fileService *httpserver.HttpFileService) error { - data, err := ioutil.ReadFile(conf.Worker[0].CreateIgnPath) + data, err := os.ReadFile(conf.Worker[0].CreateIgnPath) if err != nil { logrus.Errorf("error reading Ignition file: %v", err) return err diff --git a/cmd/template.go b/cmd/template.go index d82ea2a..cefd99a 100644 --- a/cmd/template.go +++ b/cmd/template.go @@ -17,11 +17,11 @@ limitations under the License. package cmd import ( - "io/ioutil" "nestos-kubernetes-deployer/cmd/command" "nestos-kubernetes-deployer/cmd/command/opts" "nestos-kubernetes-deployer/pkg/configmanager/asset" "nestos-kubernetes-deployer/pkg/utils" + "os" "runtime" "github.com/sirupsen/logrus" @@ -63,7 +63,7 @@ func createTemplate(cmd *cobra.Command, args []string) error { if file == "" { file = "./template.yaml" } - if err := ioutil.WriteFile(file, data, utils.DeployConfigFileMode); err != nil { + if err := os.WriteFile(file, data, utils.DeployConfigFileMode); err != nil { logrus.Errorf("Faild to write template config file: %v", err) return err } diff --git a/docs/config_file_desc.md b/docs/config_file_desc.md index 6fca0f1..0bcafb6 100644 --- a/docs/config_file_desc.md +++ b/docs/config_file_desc.md @@ -1,4 +1,4 @@ -# 配置文件说明 +# 集群配置文件说明 NestOS镜像下载地址见[官网](https://nestos.openeuler.org/) ``` shell diff --git a/docs/globalconfig_file_desc.md b/docs/globalconfig_file_desc.md new file mode 100644 index 0000000..4561dba --- /dev/null +++ b/docs/globalconfig_file_desc.md @@ -0,0 +1,8 @@ +# 全局配置文件说明 + +``` shell +persistdir: /etc/nkd # 文件存储路径,包括全局配置文件、集群配置文件以及证书文件等。默认路径:/etc/nkd +bootstrapurl: + bootstrap_ign_host: "" # 用于引导ignition文件的http服务的域名或者IP地址。默认为宿主机ip地址 + bootstrap_ign_port: "9080" # 用于引导ignition文件的http服务的端口,默认端口号为9080 +``` \ No newline at end of file diff --git a/docs/ignition_design.md b/docs/ignition_design.md index c5a0149..f92a584 100644 --- a/docs/ignition_design.md +++ b/docs/ignition_design.md @@ -3,6 +3,8 @@ Ignition是NestOS在initramfs期间用来操作磁盘的实用程序。其中包括创建用户、添加受信的SSH密钥、写入文件(常规文件、systemd服务...)、网络配置等。首次启动时,Ignition读取其配置并应用该配置。Ignition使用JSON配置文件来表示要进行的更改集。此配置的格式在[规范](https://coreos.github.io/ignition/specs/)中有详细说明。 ## 提供配置 +生成部署集群所需的Ignition(controlplane.ign)文件约为90KB,文件中声明了集群部署所需的systemd服务、证书等。在OpenStack平台上部署集群时,由于Nova用户数据限制为64KB,因此无法直接部署基础设施。为了解决这个问题,NKD创建了一个较小的Ignition(*-merge.ign)文件,作为创建基础设施时的引导配置文件。而主要的Ignition文件将会加载到可以通过 HTTP 服务访问的内存中,使较小的Ignition文件在系统引导阶自动加载主要的Ignition文件。 + 当集群节点的基础设施正常创建后,操作系统处于引导阶段,Ignition将获取配置信息并将配置文件(用户、集群证书、集群部署服务等)写入到节点机器的磁盘中,然后启动systemd服务。当"release-image-pivot.service"服务正常启动后,节点机器通过rpm-ostree机制将文件系统切换为基于NestOS的kubernetes定制版本,之后启动K8S集群部署服务,开始正式的集群部署任务,直到集群部署完成后服务关闭。 ### ControlPlane Node @@ -16,3 +18,34 @@ Master节点的Ignition文件配置信息如图: ### Worker Node Worker节点的Ignition文件配置信息如图: ![ignition_design_3](/docs/figures/ignition_design_3.jpg) + +生成的Ignition文件目录结构如下: +``` shell +$ tree +. +├── controlplane.ign +├── controlplane-merge.ign +├── master.ign +├── master-merge.ign +├── worker.ign +└── worker-merge.ign +``` +```shell +较小的"*-merge.ign"Ignition文件的内容如下: +其中: + - IP:部署HTTP服务的地址,默认为宿主机IP地址 + - port:HTTP服务的访问端口,默认端口为9080 + - {*.ign}:执行集群部署的主要Ignition文件 +{ + "ignition": { + "config": { + "merge": [ + { + "source": "http://{IP}:{port}/{*.ign}" + } + ] + }, + "version": "3.2.0" + } +} +``` \ No newline at end of file diff --git a/docs/manual.md b/docs/manual.md index 0ef2e47..0c7c505 100644 --- a/docs/manual.md +++ b/docs/manual.md @@ -12,16 +12,22 @@ ``` ``` shell # 安装arm64版本 - $ wget https://github.com/opentofu/opentofu/releases/download/v1.6.0-rc1/tofu_1.6.0-rc1_arm.rpm - $ rpm -ivh tofu_1.6.0-rc1_arm.rpm + $ wget https://github.com/opentofu/opentofu/releases/download/v1.6.0-rc1/tofu_1.6.0-rc1_arm64.rpm + $ rpm -ivh tofu_1.6.0-rc1_arm64.rpm ``` - * 选择openstack平台部署集群,需要提前搭建好openstack环境 - * 选择libvirt平台部署集群,需要提前安装libvirt虚拟化环境 * 安装NKD * 选择拷贝编译好的NKD二进制文件直接使用 * 根据以下编译安装说明编译安装NKD +## 支持平台 + +### libvirt +libvirt平台部署集群,需要提前安装libvirt虚拟化环境 + +### openstack +openstack平台部署集群,需要提前搭建好openstack环境 + ## 编译安装 * 编译环境:Linux x86_64/aarch64 @@ -40,6 +46,21 @@ $ sh hack/build.sh ``` +## 配置管理 + +### 全局配置 +全局配置文件用于管理整个集群(多集群)的配置,具体的配置项参数和默认配置详见[全局配置文件说明](/docs/globalconfig_file_desc.md) + +全局配置项参数: + - bootstrap_ign_host:用于引导ignition文件的http服务的域名或者IP地址 + - bootstrap_ign_port:用于引导ignition文件的http服务的端口 + +备注: +http服务默认监听的地址是0.0.0.0,这样能保障运行环境为多网卡时均能接收到请求。如果部署集群节点可直接访问NKD的运行环境,"bootstrap_ign_host"参数项可以为空,NKD默认会探测路由表默认最高优先级的IP地址;如果部署集群节点无法直接访问NKD的运行环境,"bootstrap_ign_host"参数项需要进行配置,并确保所指定的域名或IP地址能够被集群节点所在的网络环境的DNS服务解析到NKD的运行环境。 + +### 集群配置 +集群配置文件用于对每个集群独立配置,具体的配置项参数和默认配置详见[集群配置文件说明](/docs/config_file_desc.md) + ## 基本功能 在“部署集群”章节中有部署集群的具体过程,这里列出了NKD的基本执行指令: @@ -138,7 +159,7 @@ ``` shell $ nkd deploy --master-ips 192.168.132.11 --master-ips 192.168.132.12 --master-hostname k8s-master01 --master-hostname k8s-master02 --master-cpu 8 --worker-hostname k8s-worker01 --worker-disk 50 ``` - - 此外更精细化的配置,可以通过配置文件部署集群,具体的配置项参数以及参数默认配置详见[配置文件说明](/docs/config_file_desc.md) + - 此外更精细化的配置,可以通过集群配置文件部署集群,详情见配置管理。 ``` shell $ nkd deploy -f cluster_config.yaml ``` diff --git a/pkg/cert/K8sCertKeyGenerator.go b/pkg/cert/K8sCertKeyGenerator.go index dfcb238..baf7364 100644 --- a/pkg/cert/K8sCertKeyGenerator.go +++ b/pkg/cert/K8sCertKeyGenerator.go @@ -21,8 +21,8 @@ import ( "crypto/rsa" "crypto/x509" "crypto/x509/pkix" - "io/ioutil" "net" + "os" "time" "github.com/pkg/errors" @@ -30,12 +30,12 @@ import ( // SetUserCA 读取用户提供的各类ca证书和密钥路径中的内容 func setUserCA(a *SelfSignedCertKey, certPath, keyPath string) error { - cacert, err := ioutil.ReadFile(certPath) + cacert, err := os.ReadFile(certPath) if err != nil { return err } - cakey, err := ioutil.ReadFile(keyPath) + cakey, err := os.ReadFile(keyPath) if err != nil { return err } diff --git a/pkg/configmanager/globalconfig/globalconfig.go b/pkg/configmanager/globalconfig/globalconfig.go index 5fc1a12..45e7475 100644 --- a/pkg/configmanager/globalconfig/globalconfig.go +++ b/pkg/configmanager/globalconfig/globalconfig.go @@ -120,8 +120,7 @@ func (ga *GlobalConfig) Persist() error { logrus.Errorf("failed to marshal global config: %v", err) return err } - - if err := os.WriteFile(ga.PersistDir, globalConfigData, 0644); err != nil { + if err := os.WriteFile(filepath.Join(ga.PersistDir, GlobalConfigFile), globalConfigData, 0644); err != nil { logrus.Errorf("failed to write global config file: %v", err) return err } diff --git a/test/httpserver_test/httpserver_test.go b/test/httpserver_test/httpserver_test.go index 98647fe..7cf504e 100644 --- a/test/httpserver_test/httpserver_test.go +++ b/test/httpserver_test/httpserver_test.go @@ -17,7 +17,7 @@ limitations under the License. package httpserver_test import ( - "io/ioutil" + "io" "nestos-kubernetes-deployer/pkg/fileserver" "net/http" "testing" @@ -45,7 +45,7 @@ func TestHttpFileService(t *testing.T) { defer resp.Body.Close() // Read the response body content - respBody, err := ioutil.ReadAll(resp.Body) + respBody, err := io.ReadAll(resp.Body) if err != nil { t.Fatalf("Error reading response body: %v", err) } -- Gitee