随着“中兴事件”不断升级,引发了国人对国产自主可控技术的高度关注;本人做为所在单位的运维工程师,也但愿能找到一个稳定、能兼容国产CPU的一整套架构方案,来构建IaaS平台和PaaS平台,知足单位对安全自主可控的需求。要基于全国产方式解决公司业务需求至少要在软硬件层面知足,而国内基本都是基于x86解决方案,想找到知足需求的国产化解决方案仍是很是困难的事情。但笔者因为一个偶然的机会,接触到了国产的芯片厂商和云计算厂商,并得知他们已经实现了全国产化的云计算平台,笔者也亲自动手体验了安装部署该云计算平台,并在其之上安装部署了容器平台。上篇我给你们分享了国产CPU的服务器华芯通和国产云平台ZStack试用体验,接下来将为你们详细分享如何基于ZStack云主机构建K8S集群。node
这里要提一下,为何咱们不直接使用物理ARM服务器部署K8S集群,这跟单位测试场景有关系,既要使用云主机透传GPU计算卡进行大量的计算,又要实现容器管理平台。何况国外主流的K8S集群一般是跑在虚拟机里面的,运行在虚拟机里面的好处有不少,好比能够实现资源定制分配、利用云平台API接口能够快速生成K8S集群Node节点、更好的灵活性以及可靠性;在ZStack ARM云平台上能够同时构建IaaS+PaaS混合平台,知足不一样场景下的需求。linux
因为篇幅有限下面先介绍一下如何在基于ZStack For ARM平台中云主机部署K8S集群,整个部署过程大概花1小时(这主要是访问部分国外网络时不是很顺畅)。git
集群环境介绍: github
在本环境中用于构建K8S集群所需的资源,为基于ZStack构建的平台上的云主机:golang
ZStack云主机K8S集群架构docker
1、准备工做express
配置主机名apache
hostnamectl set-hostname K8S-Master hostnamectl set-hostname K8S-Node1 hostnamectl set-hostname K8S-Node2 hostnamectl set-hostname K8S-Node3
全部云主机上关闭swap分区 不然会报错;该操做只需在云主机环境下执行,物理机环境无需操做。json
sudo swapoff -a
step 1: 安装必要的一些系统工具ubuntu
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
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 <<EOF >/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
初始化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集群。
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
为了让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
分别在K8S-Node一、K8S-Node二、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状时,此时就可使用这个集群了
克隆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 <this_file> # ------------------- 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: <none> Selector: k8s-app=kubernetes-dashboard Type: NodePort IP: 10.111.189.106 Port: <unset> 9090/TCP TargetPort: 9090/TCP NodePort: <unset> 30090/TCP 此端口为外部访问端口 Endpoints: 10.244.2.4:9090 Session Affinity: None External Traffic Policy: Cluster Events: <none>
注意:若是在部署K8S-Dashboard界面过程当中若是则登陆UI的时候会报错:
这是由于K8S在1.6版本之后启用了RBAC访问控制策略,可使用kubectl或Kubernetes API进行配置。使用RBAC能够直接受权给用户,让用户拥有受权管理的权限,这样就再也不须要直接触碰Master Node。按照上面部署步骤则能够避免。
至此,基于ARM环境的K8S集群就部署完成了。
先说说关于ZStack安装部署的一些心得,整个ZStack For ARM平台部署到业务环境构建的过程,都是比较流畅的。ZStack产品化程度高,安装过程很是简单,基本上按照官方部署文档1个小时内就能完成3台规模的云平台搭建及平台初始化工做。
ZStack云平台采用独特的异步架构,大大提高了平台响应能力,使得批量并发操做再也不成为烦恼;管理层面与业务层面独立,不会由于管理节点意外宕机致使业务中断;平台内置大量实用性很高的功能,极大方便了在测试过程当中运维任务;版本升级简单可靠,彻底实现5分钟跨版本无缝升级,经实测升级过程当中彻底不影响业务正常运行。经过升级后能实现异构集群管理,也就是说在ARM服务器上构建管理节点,能够同时管理ARM集群中的资源,也能管理X86架构集群中的资源;同时实现高级SDN功能。
而基于ZStack云主机构建K8S集群时,咱们团队在选择方案的时候,也拿物理机和云主机作过一系列对比,对比以后发现当我用ZStack云主机部署K8S集群的时候更加灵活、可控。具体的能够在如下几个方面体现:
一、ZStack云主机天生隔离性好
对容器技术了解的人应该清楚,多个容器公用一个Host Kernel;这样就会遇到隔离性方面的问题,虽然随着技术发展,目前也可使用Linux系统上的防御机制实现安全隔离,可是从某个层面讲并非彻底隔离,而云主机方式受益于虚拟化技术,天生就有很是好的隔离性,从而能够进一步保障安全。ZStack就是基于KVM虚拟化技术架构自研。
二、受益于ZStack云平台多租户
在物理服务器上运行的大堆容器要实现资源自理,所谓资源自理就是各自管理本身的容器资源,那么这个时候问题就来了,一台物理机上有成千上万个容器怎么去细分管理范围呢?这个时候云平台的多租户管理就派上用处了,每一个租户被分配到相应的云主机,各自管理各自的云主机以及容器集群。同时还能对不一样人员权限进行控制管理。在本次测试的ZStack For ARM云平台,就能够实现按企业组织架构方式进行资源、权限管理,同时还能实现流程审批,审批完成后自动建立所需的云主机;听说后面发布的ZStack2.5.0版本还有资源编排功能。
3.ZStack云平台灵活性、自动化程度高
经过ZStack,能够根据业务需求,对云主机进行资源定制,减小资源浪费。同时根据自身业务状况调整架构实现模式,好比:有计算密集型业务,此时能够借助GPU透传功能,将GPU透传到云主机,能快速实现计算任务,避免过多繁琐配置。
另外目前各类云平台都有相应API接口,能够方便第三方应用直接调用,从而实现根据业务压力自动进行资源伸缩。可是对于物理服务器来讲没什么完整的API接口,基本上都是基于IPMI方式进行管理,并且每一个厂商的IPMI还不通用,很难实现资源的动态伸缩。说到API接口,我了解到的ZStack云平台,具有全API接口开放的特色。可使容器集群根据业务压力自动伸缩。
四、可靠性很是好
为何这么说呢?其实不难理解,计划内和计划外业务影响少。当咱们对物理服务器进行计划内维护时,那些单容器运行的业务一定会受影响,此时能够借助云平台中的热迁移功能,迁移的过程当中可实现业务不中断。对于计划外停机,对业务影响基本上都是按天算的,损失不可言表。若是采用云平台方式业务中断时间将会缩短到分钟级别。
上面简单分享了一下用云主机构建K8S集群的一些优势,固然也有一些缺点,在我看来缺点无非就是性能有稍微点损失,总之利大于弊。能够在规划时规避掉这个问题,好比能够将性能型容器资源集中放到物理Node上,这样就能够完美解决了。
最后再说说在ZStack ARM架构的云主机上部署K8S须要注意的地方,为你们提供一些参考。
一、默认Get下来的yaml配置文件,里面涉及的image路径都是x86架构的amd64,须要将其改为arm64。
二、在建立集群的时候,若是采用flannel网络模式则--pod-network-cidr必定要为 10.244.0.0/16,不然Pod网可能不通。
三、云主机环境必定要执行sudo swapoff -a 否则建立K8S集群的时候就会报错。
以上就是我本次的主要分享内容,欢迎你们关注交流。(qq:410185063;mail:zts@viczhu.com)。