如何基于国产CPU的云平台构建容器管理平台?(下篇)

云计算
上篇我给大家分享了国产CPU的服务器华芯通和国产云平台ZStack试用体验,接下来将为大家详细分享如何基于ZStack云主机构建K8S集群。

 随着“中兴事件”不断升级,引起了国人对国产自主可控技术的高度关注;本人作为所在单位的运维工程师,也希望能找到一个稳定、能兼容国产CPU的一整套架构方案,来构建IaaS平台和PaaS平台,满足单位对安全自主可控的需求。要基于全国产方式解决公司业务需求至少要在软硬件层面满足,而国内基本都是基于x86解决方案,想找到满足需求的国产化解决方案还是非常困难的事情。但笔者由于一个偶然的机会,接触到了国产的芯片厂商和云计算厂商,并得知他们已经实现了全国产化的云计算平台,笔者也亲自动手体验了安装部署该云计算平台,并在其之上安装部署了容器平台。上篇我给大家分享了国产CPU的服务器华芯通和国产云平台ZStack试用体验,接下来将为大家详细分享如何基于ZStack云主机构建K8S集群。

第三节 基于ZStack云主机构建K8S集群

这里要提一下,为什么我们不直接使用物理ARM服务器部署K8S集群,这跟单位测试场景有关系,既要使用云主机透传GPU计算卡进行大量的计算,又要实现容器管理平台。况且国外主流的K8S集群通常是跑在虚拟机里面的,运行在虚拟机里面的好处有很多,比如可以实现资源定制分配、利用云平台API接口可以快速生成K8S集群Node节点、更好的灵活性以及可靠性;在ZStack ARM云平台上可以同时构建IaaS+PaaS混合平台,满足不同场景下的需求。

由于篇幅有限下面先介绍一下如何在基于ZStack For ARM平台中云主机部署K8S集群,整个部署过程大概花1小时(这主要是访问部分国外网络时不是很顺畅)。

集群环境介绍:

主机名角色IP地址配置系统版本

ZStack

在本环境中用于构建K8S集群所需的资源,为基于ZStack构建的平台上的云主机:

ZStack

ZStack

ZStack云主机K8S集群架构

1、准备工作

配置主机名

hostnamectl set-hostname K8S-Master

hostnamectl set-hostname K8S-Node1

hostnamectl set-hostname K8S-Node2

hostnamectl set-hostname K8S-Node3

所有云主机上关闭swap分区 否则会报错;该操作只需在云主机环境下执行,物理机环境无需操作。

sudo swapoff -a

2、安装部署

2.1安装Docker

# step 1: 安装必要的一些系统工具

sudo apt-get update

sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common

# step 2: 安装GPG证书

curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

# Step 3: 写入软件源信息

sudo add-apt-repository "deb [arch=arm64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"

# Step 4: 更新并安装 Docker-CE

sudo apt-get -y update

sudo apt-get -y install docker-ce

使用daocloud对docker镜像下载进行加速。

curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://56d10455.m.daocloud.io

2.2安装go环境

apt-get install golang- golang

2.3 安装kubelet、kubeadm、kubectl

apt-get update && apt-get install -y apt-transport-https

curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -

cat </etc/apt/sources.list.d/kubernetes.list

deb http://apt.kubernetes.io/ kubernetes-xenial main

EOF

apt-get update

apt-get install -y kubectl kubeadm kubectl

2.4用kubeadm创建集群

初始化Master

kubeadm init --apiserver-advertise-address 172.120.194.196 --pod-network-cidr 10.244.0.0/16

执行完上面命令后,如果中途不报错会出现类似以下信息:

kubeadm join 172.120.194.196:6443 --token oyf6ns.whcoaprs0q7growa --discovery-token-ca-cert-hash sha256:30a459df1b799673ca87f9dcc776f25b9839a8ab4b787968e05edfb6efe6a9d2

这段信息主要是提示如何注册其他节点到K8S集群。

2.5 配置kubectl

Kubectl是管理K8S集群的命令行工具,因此需要对kubectl运行环境进行配置。

su - zstack

sudo mkdir -p $HOME/.kube

sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

sudo chown $(id -u):$(id -g) $HOME/.kube/config

echo "source <(kubectl completion bash)" >> ~/.bash

2.6 安装Pod网络

为了让K8S集群的Pod之间能够正常通讯,必须安装Pod网络,Pod网络可以支持多种网络方案,当前测试环境采用Flannel模式。

先将Flannel的yaml文件下载到本地,进行编辑,编辑的主要目的是将原来X86架构的镜像名称,改为ARM架构的。让其能够在ZStack ARM云环境正常运行。修改位置及内容参考下面文件中红色粗体字部分。

sudo wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

vim kube-flannel.yml

---

kind: ClusterRole

apiVersion: rbac.authorization.k8s.io/v1beta1

metadata:

name: flannel

rules:

- apiGroups:

- ""

resources:

- pods

verbs:

- get

- apiGroups:

- ""

resources:

- nodes

verbs:

- list

- watch

- apiGroups:

- ""

resources:

- nodes/status

verbs:

- patch

---

kind: ClusterRoleBinding

apiVersion: rbac.authorization.k8s.io/v1beta1

metadata:

name: flannel

roleRef:

apiGroup: rbac.authorization.k8s.io

kind: ClusterRole

name: flannel

subjects:

- kind: ServiceAccount

name: flannel

namespace: kube-system

---

apiVersion: v1

kind: ServiceAccount

metadata:

name: flannel

namespace: kube-system

---

kind: ConfigMap

apiVersion: v1

metadata:

name: kube-flannel-cfg

namespace: kube-system

labels:

tier: node

app: flannel

data:

cni-conf.json: |

{

"name": "cbr0",

"plugins": [

{

"type": "flannel",

"delegate": {

"hairpinMode": true,

"isDefaultGateway": true

}

},

{

"type": "portmap",

"capabilities": {

"portMappings": true

}

}

]

}

net-conf.json: |

{

"Network": "10.244.0.0/16",

"Backend": {

"Type": "vxlan"

}

}

---

apiVersion: extensions/v1beta1

kind: DaemonSet

metadata:

name: kube-flannel-ds

namespace: kube-system

labels:

tier: node

app: flannel

spec:

template:

metadata:

labels:

tier: node

app: flannel

spec:

hostNetwork: true

nodeSelector:

beta.kubernetes.io/arch: arm64

tolerations:

- key: node-role.kubernetes.io/master

operator: Exists

effect: NoSchedule

serviceAccountName: flannel

initContainers:

- name: install-cni

image: quay.io/coreos/flannel:v0.10.0-arm64

command:

- cp

args:

- -f

- /etc/kube-flannel/cni-conf.json

- /etc/cni/net.d/10-flannel.conflist

volumeMounts:

- name: cni

mountPath: /etc/cni/net.d

- name: flannel-cfg

mountPath: /etc/kube-flannel/

containers:

- name: kube-flannel

image: quay.io/coreos/flannel:v0.10.0-arm64

command:

- /opt/bin/flanneld

args:

- --ip-masq

- --kube-subnet-mgr

resources:

requests:

cpu: "100m"

memory: "50Mi"

limits:

cpu: "100m"

memory: "50Mi"

securityContext:

privileged: true

env:

- name: POD_NAME

valueFrom:

fieldRef:

fieldPath: metadata.name

- name: POD_NAMESPACE

valueFrom:

fieldRef:

fieldPath: metadata.namespace

volumeMounts:

- name: run

mountPath: /run

- name: flannel-cfg

mountPath: /etc/kube-flannel/

volumes:

- name: run

hostPath:

path: /run

- name: cni

hostPath:

path: /etc/cni/net.d

- name: flannel-cfg

configMap:

name: kube-flannel-cfg

sudo kubectl apply -f kube-flannel.yml

执行上面命令后会正常情况下会有如下输出:

clusterrole.rbac.authorization.k8s.io "flannel" created

clusterrolebinding.rbac.authorization.k8s.io "flannel" created

serviceaccount "flannel" created

configmap "kube-flannel-cfg" created

daemonset.extensions "kube-flannel-ds" created

2.7注册节点到K8S集群

分别在K8S-Node1、K8S-Node2、K8S-Node3

kubeadm join 172.120.194.196:6443 --token oyf6ns.whcoaprs0q7growa --discovery-token-ca-cert-hash sha256:30a459df1b799673ca87f9dcc776f25b9839a8ab4b787968e05edfb6efe6a9d2

kubectl get nodes 查看节点状态

zstack@K8S-Master:~$ kubectl get nodes

NAME STATUS ROLES AGE VERSION

k8s-master Ready master 49m v1.11.0

k8s-node1 NotReady 4m v1.11.0

k8s-node2 NotReady 4m v1.11.0

k8s-node3 NotReady 4m v1.11.0

如果发现所有节点是NotReady 是因每个节点都需要启动若干个组件,这些组件都是在Pod中运行,且需要到Google下载镜像。使用下面命令查看Pod运行状况:

kubectl get pod --all-namespaces 正常情况应该是如下的状态:

NAMESPACE NAME READY STATUS RESTARTS AGE

kube-system coredns-78fcdf6894-49tkw 1/1 Running 0 1h

kube-system coredns-78fcdf6894-gmcph 1/1 Running 0 1h

kube-system etcd-k8s-master 1/1 Running 0 19m

kube-system kube-apiserver-k8s-master 1/1 Running 0 19m

kube-system kube-controller-manager-k8s-master 1/1 Running 0 19m

kube-system kube-flannel-ds-bqx2s 1/1 Running 0 16m

kube-system kube-flannel-ds-jgmjp 1/1 Running 0 16m

kube-system kube-flannel-ds-mxpl8 1/1 Running 0 21m

kube-system kube-flannel-ds-sd6lh 1/1 Running 0 16m

kube-system kube-proxy-cwslw 1/1 Running 0 16m

kube-system kube-proxy-j75fj 1/1 Running 0 1h

kube-system kube-proxy-ptn55 1/1 Running 0 16m

kube-system kube-proxy-zl8mb 1/1 Running 0 16m

kube-system kube-scheduler-k8s-master 1/1 Running 0 19m

在整个过程中如果发现状态为Pending、ContainerCreateing、ImagePullBackOff等状态都表示Pod还未就绪,只有Running状态才是正常的。要做的事情只有等待。

kubectl get nodes 再次查看节点状态

NAME STATUS ROLES AGE VERSION

k8s-master Ready master 1h v1.11.0

k8s-node1 Ready 16m v1.11.0

k8s-node2 Ready 16m v1.11.0

k8s-node3 Ready 16m v1.11.0

当所有节点均为 Ready状时,此时就可以使用这个集群了

2.8部署kubernetes-dashboard

克隆kubernetes-dashboard yaml文件

sudo git clone https://github.com/gh-Devin/kubernetes-dashboard.git

修改kubernetes-dashboard yaml文件,修改内容为下面红色粗体部分。

cd kubernetes-dashboard/

vim kubernetes-dashboard.yaml

# Copyright 2017 The Kubernetes Authors.

#

# Licensed under the Apache License, Version 2.0 (the "License");

# you may not use this file except in compliance with the License.

# You may obtain a copy of the License at

#

# http://www.apache.org/licenses/LICENSE-2.0

#

# Unless required by applicable law or agreed to in writing, software

# distributed under the License is distributed on an "AS IS" BASIS,

# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

# See the License for the specific language governing permissions and

# limitations under the License.

# Configuration to deploy release version of the Dashboard UI compatible with

# Kubernetes 1.8.

#

# Example usage: kubectl create -f

# ------------------- Dashboard Secret ------------------- #

apiVersion: v1

kind: Secret

metadata:

labels:

k8s-app: kubernetes-dashboard

name: kubernetes-dashboard-certs

namespace: kube-system

type: Opaque

---

# ------------------- Dashboard Service Account ------------------- #

apiVersion: v1

kind: ServiceAccount

metadata:

labels:

k8s-app: kubernetes-dashboard

name: kubernetes-dashboard

namespace: kube-system

---

# ------------------- Dashboard Role & Role Binding ------------------- #

kind: Role

apiVersion: rbac.authorization.k8s.io/v1

metadata:

name: kubernetes-dashboard-minimal

namespace: kube-system

rules:

# Allow Dashboard to create 'kubernetes-dashboard-key-holder' secret.

- apiGroups: [""]

resources: ["secrets"]

verbs: ["create"]

# Allow Dashboard to create 'kubernetes-dashboard-settings' config map.

- apiGroups: [""]

resources: ["configmaps"]

verbs: ["create"]

# Allow Dashboard to get, update and delete Dashboard exclusive secrets.

- apiGroups: [""]

resources: ["secrets"]

resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs"]

verbs: ["get", "update", "delete"]

# Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.

- apiGroups: [""]

resources: ["configmaps"]

resourceNames: ["kubernetes-dashboard-settings"]

verbs: ["get", "update"]

# Allow Dashboard to get metrics from heapster.

- apiGroups: [""]

resources: ["services"]

resourceNames: ["heapster"]

verbs: ["proxy"]

- apiGroups: [""]

resources: ["services/proxy"]

resourceNames: ["heapster", "http:heapster:", "https:heapster:"]

verbs: ["get"]

---

apiVersion: rbac.authorization.k8s.io/v1

kind: RoleBinding

metadata:

name: kubernetes-dashboard-minimal

namespace: kube-system

roleRef:

apiGroup: rbac.authorization.k8s.io

kind: Role

name: kubernetes-dashboard-minimal

subjects:

- kind: ServiceAccount

name: kubernetes-dashboard

namespace: kube-system

---

# ------------------- Dashboard Deployment ------------------- #

kind: Deployment

apiVersion: apps/v1beta2

metadata:

labels:

k8s-app: kubernetes-dashboard

name: kubernetes-dashboard

namespace: kube-system

spec:

replicas: 1

revisionHistoryLimit: 10

selector:

matchLabels:

k8s-app: kubernetes-dashboard

template:

metadata:

labels:

k8s-app: kubernetes-dashboard

spec:

serviceAccountName: kubernetes-dashboard

containers:

- name: kubernetes-dashboard

image: k8s.gcr.io/kubernetes-dashboard-arm64:v1.8.3

ports:

- containerPort: 9090

protocol: TCP

args:

#- --auto-generate-certificates

# Uncomment the following line to manually specify Kubernetes API server Host

# If not specified, Dashboard will attempt to auto discover the API server and connect

# to it. Uncomment only if the default does not work.

volumeMounts:

- name: kubernetes-dashboard-certs

mountPath: /certs

# Create on-disk volume to store exec logs

- mountPath: /tmp

name: tmp-volume

livenessProbe:

httpGet:

scheme: HTTP

path: /

port: 9090

initialDelaySeconds: 30

timeoutSeconds: 30

volumes:

- name: kubernetes-dashboard-certs

secret:

secretName: kubernetes-dashboard-certs

- name: tmp-volume

emptyDir: {}

serviceAccountName: kubernetes-dashboard-admin

# Comment the following tolerations if Dashboard must not be deployed on master

tolerations:

- key: node-role.kubernetes.io/master

effect: NoSchedule

---

# ------------------- Dashboard Service ------------------- #

kind: Service

apiVersion: v1

metadata:

labels:

k8s-app: kubernetes-dashboard

name: kubernetes-dashboard

namespace: kube-system

spec:

ports:

- port: 9090

targetPort: 9090

selector:

k8s-app: kubernetes-dashboard

# ------------------------------------------------------------

kind: Service

apiVersion: v1

metadata:

labels:

k8s-app: kubernetes-dashboard

name: kubernetes-dashboard-external

namespace: kube-system

spec:

ports:

- port: 9090

targetPort: 9090

nodePort: 30090

type: NodePort

selector:

k8s-app: kubernetes-dashboard

修改完成后执行

kubectl -n kube-system create -f .

执行命令的正常输出:

serviceaccount "kubernetes-dashboard-admin" created

clusterrolebinding.rbac.authorization.k8s.io "kubernetes-dashboard-admin" created

secret "kubernetes-dashboard-certs" created

serviceaccount "kubernetes-dashboard" created

role.rbac.authorization.k8s.io "kubernetes-dashboard-minimal" created

rolebinding.rbac.authorization.k8s.io "kubernetes-dashboard-minimal" created

deployment.apps "kubernetes-dashboard" created

service "kubernetes-dashboard-external" created

然后查看kubernetes-dashboard Pod的状态

kubectl get pod --all-namespaces

NAMESPACE NAME READY STATUS RESTARTS AGE

kube-system kubernetes-dashboard-66885dcb6f-v6qfm 1/1 Running 0 8m

当状态为running 时执行下面命令查看端口

kubectl --namespace=kube-system describe svc kubernetes-dashboard

Name: kubernetes-dashboard-external

Namespace: kube-system

Labels: k8s-app=kubernetes-dashboard

Annotations:

Selector: k8s-app=kubernetes-dashboard

Type: NodePort

IP: 10.111.189.106

Port: 9090/TCP

TargetPort: 9090/TCP

NodePort: 30090/TCP 此端口为外部访问端口

Endpoints: 10.244.2.4:9090

Session Affinity: None

External Traffic Policy: Cluster

Events:

注意:如果在部署K8S-Dashboard界面过程中如果则登录UI的时候会报错:

ZStack

这是因为K8S在1.6版本以后启用了RBAC访问控制策略,可以使用kubectl或Kubernetes API进行配置。使用RBAC可以直接授权给用户,让用户拥有授权管理的权限,这样就不再需要直接触碰Master Node。按照上面部署步骤则可以避免。

ZStack

ZStack

至此,基于ARM环境的K8S集群就部署完成了。

第四节 全篇总结

先说说关于ZStack安装部署的一些心得,整个ZStack For ARM平台部署到业务环境构建的过程,都是比较流畅的。ZStack产品化程度高,安装过程非常简单,基本上按照官方部署文档1个小时内就能完成3台规模的云平台搭建及平台初始化工作。

ZStack云平台采用独特的异步架构,大大提升了平台响应能力,使得批量并发操作不再成为烦恼;管理层面与业务层面独立,不会因为管理节点意外宕机导致业务中断;平台内置大量实用性很高的功能,极大方便了在测试过程中运维任务;版本升级简单可靠,完全实现5分钟跨版本无缝升级,经实测升级过程中完全不影响业务正常运行。通过升级后能实现异构集群管理,也就是说在ARM服务器上构建管理节点,可以同时管理ARM集群中的资源,也能管理X86架构集群中的资源;同时实现高级SDN功能。

而基于ZStack云主机构建K8S集群时,我们团队在选择方案的时候,也拿物理机和云主机做过一系列对比,对比之后发现当我用ZStack云主机部署K8S集群的时候更加灵活、可控。具体的可以在以下几个方面体现:

1、ZStack云主机天生隔离性好

对容器技术了解的人应该清楚,多个容器公用一个Host Kernel;这样就会遇到隔离性方面的问题,虽然随着技术发展,目前也可以使用Linux系统上的防护机制实现安全隔离,但是从某个层面讲并不是完全隔离,而云主机方式受益于虚拟化技术,天生就有非常好的隔离性,从而可以进一步保障安全。ZStack就是基于KVM虚拟化技术架构自研。

2、受益于ZStack云平台多租户

在物理服务器上运行的大堆容器要实现资源自理,所谓资源自理就是各自管理自己的容器资源,那么这个时候问题就来了,一台物理机上有成千上万个容器怎么去细分管理范围呢?这个时候云平台的多租户管理就派上用处了,每个租户被分配到相应的云主机,各自管理各自的云主机以及容器集群。同时还能对不同人员权限进行控制管理。在本次测试的ZStack For ARM云平台,就可以实现按企业组织架构方式进行资源、权限管理,同时还能实现流程审批,审批完成后自动创建所需的云主机;据说后面发布的ZStack2.5.0版本还有资源编排功能。

3.ZStack云平台灵活性、自动化程度高

通过ZStack,可以根据业务需求,对云主机进行资源定制,减少资源浪费。同时根据自身业务情况调整架构实现模式,比如:有计算密集型业务,此时可以借助GPU透传功能,将GPU透传到云主机,能快速实现计算任务,避免过多繁琐配置。

另外目前各种云平台都有相应API接口,可以方便第三方应用直接调用,从而实现根据业务压力自动进行资源伸缩。但是对于物理服务器来说没什么完整的API接口,基本上都是基于IPMI方式进行管理,而且每个厂商的IPMI还不通用,很难实现资源的动态伸缩。说到API接口,我了解到的ZStack云平台,具备全API接口开放的特点。可以使容器集群根据业务压力自动伸缩。

4、可靠性非常好

为什么这么说呢?其实不难理解,计划内和计划外业务影响少。当我们对物理服务器进行计划内维护时,那些单容器运行的业务必定会受影响,此时可以借助云平台中的热迁移功能,迁移的过程中可实现业务不中断。对于计划外停机,对业务影响基本上都是按天算的,损失不可言表。如果采用云平台方式业务中断时间将会缩短到分钟级别。

上面简单分享了一下用云主机构建K8S集群的一些优点,当然也有一些缺点,在我看来缺点无非就是性能有稍微点损失,总之利大于弊。可以在规划时规避掉这个问题,比如可以将性能型容器资源集中放到物理Node上,这样就可以***解决了。

***再说说在ZStack ARM架构的云主机上部署K8S需要注意的地方,为大家提供一些参考。

1、默认Get下来的yaml配置文件,里面涉及的image路径都是x86架构的amd64,需要将其改成arm64。

2、在创建集群的时候,如果采用flannel网络模式则--pod-network-cidr一定要为 10.244.0.0/16,否则Pod网可能不通。

3、云主机环境一定要执行sudo swapoff -a 不然创建K8S集群的时候就会报错。

以上就是我本次的主要分享内容,欢迎大家关注交流。(qq:410185063;mail:zts@viczhu.com)。

责任编辑:赵立京 来源: 51CTO
相关推荐

2018-07-16 22:13:54

CPU容器

2019-02-14 14:44:48

2019-11-18 23:24:52

云途腾

2009-09-16 13:25:11

IT综合管理平台

2018-07-05 22:31:02

云计算云计算管理平台CMP

2021-07-27 08:01:22

CICD平台

2020-12-10 06:46:40

容器云平台

2017-09-26 09:35:22

2016-09-19 10:01:01

2010-11-11 17:44:18

云计算IBM

2019-08-16 11:48:53

容器云平台软件

2019-04-04 10:39:23

云平台云架构云计算

2009-05-18 17:57:22

IT系统虚拟化

2023-03-15 07:22:56

画像平台数据中台

2012-10-25 21:27:27

云计算SaaS

2022-09-28 07:38:29

金融容器云平台

2012-09-13 17:02:07

Zendesk云计算

2017-05-16 08:24:37

WebSocket容器应用

2010-11-12 09:26:10

云计算
点赞
收藏

51CTO技术栈公众号