kubernetes-部署

kubernetes-部署

  • 部署kubernetes master

  • 部署容器网络插件

  • 部署worker节点

  • 部署dashboard可视化插件

  • 部署容器存储插件

  • 以下操作均是在centos7.6进行

  1. 部署kubernetes master
# curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && curl -o  /etc/yum.repos.d/docker-ce.repo  http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg         https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

# 关闭selinux
# sed -i 's/enforcing/disabled/g' /etc/sysconfig/selinux

安装基础组件

# yum install -y kubelet kubeadm kubectl docker-ce vim iptables-services wget  net-tools 

# systemctl start docker && systemctl enable docker kubelet

导入基础镜像

# docker load -i k8s1.15.1.tar

注:以上操作需要在所有节点执行,本次部署需要有互联网支持

master节点进行初始化

忽略swap报错

# vim /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS="--fail-swap-on=false"

安装

# kubeadm  init --pod-network-cidr=10.244.0.0/16  --service-cidr=10.96.0.0/12  --ignore-preflight-errors=Swap --kubernetes-version=v1.15.1
注:10.244.0.0/16为pod网络  server网络默认为10.96.0.0/12

kubectl 客户端用户配置文件配置

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

记录安装后输出,供后面添加node节点使用

# kubeadm join 192.168.1.170:6443 --token gpy810.gaq18z5bnks9occf    \
--discovery-token-ca-cert-hash sha256:747559b3a32db293cd063a77559c85d04469026145d99cf97fe4fac002717512

查看节点信息

# kubectl get nodes 
NAME                    STATUS   ROLES    AGE   VERSION
master.k8s.com   NotReady    master   38m   v1.15.1

以上的get输出结果可以看到,master节点的状态是NotReady,在调试k8s集群时,最重要的手段就是用kubectl describe 命令查看节点(node)对象的详细信息、状态和事件(Event),执行以下命令进行排查

# kubectl describe node master

...
Conditions:
...

Ready   False ... KubeletNotReady  runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized

通过kubectl describe 命令输出可以看到,NotReady的原因是还没有部署网络插件

另外,还可以通过kubectl检查这个节点上各个系统pod的状态,其中,kube-system是k8s预留的系统pod的工作空间。

# kubectl get pods -n kube-system

NAME               READY   STATUS   RESTARTS  AGE
coredns-78fcdf6894-j9syh     0/1    Pending  0     1h
coredns-78fcdf6894-jm8df     0/1    Pending  0     1h
etcd-master           1/1    Running  0     2s
kube-apiserver-master      1/1    Running  0     1s
kube-controller-manager-master  0/1    Pending  0     1s
kube-proxy-xb7u7         1/1    NodeLost  0     1h
kube-scheduler-master      1/1    Running  0     1s

可以看到,coredns、kube-controller-manager等依赖于网络的pod都处于Pending状态,也就是调度失败,这是符合预期效果的,因为这个master节点的网络还没部署。

  1. 部署容器网络插件
# kubectl apply -f kube-flannel.yml

部署完成后,可以通过kubectl get 重新检查一遍pod状态。

# kubectl get pods -n kube-system
NAME                                     READY   STATUS    RESTARTS   AGE
coredns-5c98db65d4-cp2zj                 1/1     Running   0          11d
coredns-5c98db65d4-t6rqq                 1/1     Running   0          11d
etcd-master.k8s.com                      1/1     Running   0          11d
kube-apiserver-master.k8s.com            1/1     Running   0          11d
kube-controller-manager-master.k8s.com   1/1     Running   0          11d
kube-flannel-ds-amd64-gkck5              1/1     Running   1          11d
kube-proxy-gjswz                         1/1     Running   1          11d
kube-proxy-s48w4                         1/1     Running   0          11d
kube-scheduler-master.k8s.com            1/1     Running   0          11d

可以看到,所有的pod都启动成功了,而刚刚部署的flannel网络插件则在kube-system新建了一个名叫kube-flannel-ds-amd64-gkck5的pod,一般来说,这些pod就是容器网络插件在每个节点上的控制组件。

k8s支持容器网络插件,使用的是一个叫CNI的通用接口,它也是当前容器网络的标准,市面上所的所有容器网络开源项目都可以通过CNI接入k8s,比如刚部署的flannel还有calico、canal、romana等等,它们的部署方式也都是类似的“一键部署”。

至此k8s的master节点就部署完成了,如果只需要一个蛋节点的k8s,现在就可以使用了,不过在默认情况下,k8s的master节点是不能运行用户pod的,所以还需要额外做一个小操作。

使用taint/toleration调整master执行pod的策略。

它的原理非常简单,一旦某个节点被加上一个taint,也就是被打上了“污点”,那么所有pod就都不能在这个节点上运行,因为k8s是有洁癖的。

除非有个别的pod声明自己能“容忍”这个“污点”,也就是声明了toleration,它才可以在这个节点上运行。

其中,为节点打上"污点"(taint)的命令如下:

# kubectl taint nodes master.k8s.com foo=bar:NoSchedule

这时master.k8s.com这台master节点就会增加一个键值对格式的taint,其中值里面的NoSchedule,意味着这个taint只会在调度新pod的时候生效,而不会影响到已经发布到master节点上的pod,即便他们没有toleration。

声明toleration,只需要在pod的yaml文件中spec部分,加入tolerations字段即可,如下:

apiVersion: v1
kind: Pod
...
spec:
  tolerations:
  - key: "foo"
    operator: "Equal"
    value: "bar"
    effect: "NoSchedule"

这个toleration的含义是,这个pod能“容忍”所有键值对为foo=bar的taint(operator:"Equal",“等于”操作)。

回到已经部署的集群个上,这时,如果通过kubectl describe检查一下master节点的taint字段,就会有些发现

kubectl describe node master

Name:               master
Roles:              master
Taints:             node-role.kubernetes.io/master:NoSchedule

可以看到,master节点默认被加上了node-role.kubernetes.io/master:NoSchedule这样一个“污点”,其中"键"是node-role.kubernetes.io/master,而没有提供“值”。

此时,就需要像下面这样用“Exists”操作符(operator:"Exists",“存在”即可)来说明,该pod能够容忍所有以foo为键的taint,才能让这个pod运行在该master节点上。

apiVersion: v1
kind: Pod
...
spec:
  tolerations:
  - key: "foo"
    operator: "Exists"
    effect: "NoSchedule"

当然,如果就是像要一个单节点的k8s,删除这个taint才是正确的选择,操作如下:

kubectl taint nodes --all node-role.kubernetes.io/master-

在“node-role.kubernetes.io/master”这个键后面加上了一个短横线"-",这个格式就意味着移除所有以“node-role.kubernetes.io/master”为键的taint

  1. 部署worker节点

node节点执行刚才获取的命令

# kubeadm join 192.168.1.170:6443 --token gpy810.gaq18z5bnks9occf    \
--discovery-token-ca-cert-hash sha256:747559b3a32db293cd063a77559c85d04469026145d99cf97fe4fac002717512

查看节点信息

# kubectl  get nodes
NAME                    STATUS   ROLES    AGE   VERSION
master.k8s.com   Ready    master   38m   v1.15.1
node.k8s.com            Ready    <none>   34m   v1.15.1

有了kubeadm这样的原生管理工具,k8s的部署已经被大大简化,更重要的是,像证书、授权、各个组件的配置等部署中最麻烦的操作,kubeadm都已经帮忙完成了。

至此,整个k8s集群就部署完成了,可以使用命令行的方式进行应用的发布和管理了,但是用起来可能不是很爽,下面就介绍下k8s的dashboard的部署方式。

  1. 部署dashboard可视化插件

在k8s社区中,又一个很受欢迎的dashboard项目,它可以给用户提供一个可视化的web界面来查看当前集群的各种信息,毫不意外,它的部署也相当简单。

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml

部署完成后我们可以查看dashboard的pod状态。

#  kubectl get pods -n kube-system
kubernetes-dashboard-6f9887bccc-qc47t    1/1     Running   1          11d

需要注意的是,由于dashboard是一个web server,很多人经常会在自己的公有云上无意地暴露dashborad的端口,从而造成安全隐患,所以,1.7版本之后的dashboard部署完成后,默认只能通过proxy的方式在本地访问,具体操作,可以查看dashboard的官方文档。

而如果想从集群外访问这个dashboard的话,就需要用到ingress。

  1. 部署容器存储插件

很多时候我们需要用数据卷(volume)把外面宿主机上的目录或者文件挂载进容器的mount namespace中,从而达到容器和宿主机共享这些目录或文件的目的,容器里的应用就可以在这些数据卷中新建和写入文件了。

可是,如果在某一台机器上启动一个容器,显然无法看到其他机器上的容器在它们的数据卷里写入的文件,这就是容器最典型的特征之一:无状态

而容器的持久化存储,就是用来保存容器存储状态的重要手段,存储插件会在容器里挂载一个基于网络或其他机制的远程数据卷,使得在容器里创建的文件,实际上保存在远程存储服务器上,或者以分布式的方式保存在多个节点上,而与当前宿主机没有任何绑定关系,这样无论在其他哪个宿主机上启动新的容器,都可以请求挂载指定的持久化存储卷,从而访问到数据卷里的的数据,这就是"持久化"的含义。

由于k8s本身的松耦合设计,绝大多数存储项目,如ceph、glusterfs、nfs等,都可以为k8s提供持久化存储能力,在这次的部署实战中,选择了rook插件进行存储的部署实验。

rook是一个基于ceph的k8s存储插件(它后期也在加入对更多存储实现的支持),不同ceph的简单封装,rook在自己的实现中加入了水平扩展、迁移、灾难备份、监控等大量的企业级功能,使得这个项目变成了一个完整的,生产级别可用的容器存储插件。

得益于容器化技术,以下三条命令就可以将rook部署起来,如下:

# kubectl  apply -f https://raw.githubusercontent.com/rook/rook/master/cluster/examples/kubernetes/ceph/common.yaml

# kubectl apply -f https://raw.githubusercontent.com/rook/rook/master/cluster/examples/kubernetes/ceph/operator.yaml

# kubectl apply -f https://raw.githubusercontent.com/rook/rook/master/cluster/examples/kubernetes/ceph/cluster.yaml

在部署完成后,就可以看到rook项目会将自己的pod放置在由它自己管理的namespace当中,如下:

# kubectl  get pod -n rook-ceph
NAME                                            READY   STATUS        RESTARTS   AGE
csi-cephfsplugin-provisioner-7c85779954-cz7g4   4/4     Running       0          5m11s
csi-cephfsplugin-provisioner-7c85779954-dmcq2   4/4     Running       0          5m11s
csi-cephfsplugin-th86r                          3/3     Running       0          5m11s
csi-rbdplugin-provisioner-5474976bf6-6vx2n      5/5     Running       0          5m11s
csi-rbdplugin-provisioner-5474976bf6-lnr4t      5/5     Running       0          5m11s
csi-rbdplugin-sb6qj                             3/3     Running       0          5m11s
rook-ceph-agent-rx7jf                           1/1     Running       0          5m13s
rook-ceph-detect-version-fww7w                  0/1     Terminating   0          11s
rook-ceph-operator-b947787bc-b2kvd              1/1     Running       0          7m10s
rook-discover-rc59k                             1/1     Running       0          5m13s

这样,一个基于rook持久化存储集群就以容器的方式运行起来了,而接下来在k8s上创建的所有pod就能够通过persistent volume(PV)和persistent volume claim(pvc)的方式,在容器里挂载由ceph提供的数据卷里。

而rook则会负责这些数据卷的生命周期管理、灾难备份等运维工作。

选择rook其实是因为这个项目很有前途,如果去研究下rook项目的实现,就会发现它巧妙地依赖了k8s提供等编排能力,合理的使用了很多诸如operator、CRD等重要的扩特性,这使得rook成为了目前社区中机遇k8s api构建的最完善也最成熟的容器存储插件,可以想象,应该很快就会得到整个社区的推崇。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容