回望K8S Kubernetes拼图

kubernetes 安装

all 节点安装 DockerKubeadm

所有节点 root 用户下操作

> 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
# 这一步安装的时候 kubeadm 和 kubelet、kubectl、kubernetes-cni 都会自动安装完毕
> apt-get install -y docker.io kubeadm

提示:如果 apt.kubernetes.io 因为网络问题访问不到,可以换成中科大的 Ubuntu 镜像源 deb http://mirrors.ustc.edu.cn/kubernetes/apt kubernetes-xenial main。

部署 Kubernetes Master

声明一个 kubeadm.yaml

---
apiVersion: kubeadm.k8s.io/v1alpha1
kind: MasterConfiguration
controllerManagerExtraArgs:
# 配置了自定义自动水平扩展
  horizontal-pod-autoscaler-use-rest-clients: "true"
  horizontal-pod-autoscaler-sync-period: "10s"
  node-monitor-grace-period: "10s"
apiServerExtraArgs:
  runtime-config: "api/all=true"
#  kubeadm 部署的 kubernetes 的版本
kubernetesVersion: "stable-1.11"
···

执行下面的指令,完成 kubernetes master 部署,这回生成一行指令

> kubeadm init --config kubeadm.yaml
kubeadm join 10.168.0.2:6443 --token 00bwbx.uvnaa2ewjflwu1ry --discovery-token-ca-cert-hash sha256:00eb62a2a6020f94132e3fe1ab721349bbcd3e9b94da9654cfe15f2985ebd711

这个 kubeadm join 命令, 用来给这个 Master 节点添加更多的 Worker 节点.

另外 kubeadm 会提示我们第一次使用 kubernetes 集群所需要的配置命令:

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

因为 Kubernetes 集群默认需要加密方式访问,所以,需要将刚刚部署生成的 kubernetes 集群安全配置文件,保存到当前用户的 .kube 目录下, kubectl 默认会使用这个目录下的授权信息进行访问

#查看kubernetes集群的节点状态
> kubectl get nodes
NAME      STATUS     ROLES     AGE       VERSION
master    NotReady   master    1d        v1.11.1

# NotReady 因为还没有部署任何网络插件
> 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 get pods -n kube-system
NAME                            READY   STATUS   RESTARTS  AGE
coredns-78fcdf6894-j9s52        0/1     Pending  0         1h
coredns-78fcdf6894-jm4wf        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-xbd47                1/1     NodeLost 0         1h
kube-scheduler-master           1/1     Running  0         1s

部署 容器网络插件

kubernetes 内部里面 一切皆容器 设计方式,部署网络插件非常简单,以 Weave 为例子

> kubectl apply -f https://git.io/weave-kube-1.6

部署完毕后, 通过 kubectl get 检查 POD 状态

> kubectl get pods -n kube-system
NAME                             READY     STATUS    RESTARTS   AGE
coredns-78fcdf6894-j9s52         1/1       Running   0          1d
coredns-78fcdf6894-jm4wf         1/1       Running   0          1d
etcd-master                      1/1       Running   0          9s
kube-apiserver-master            1/1       Running   0          9s
kube-controller-manager-master   1/1       Running   0          9s
kube-proxy-xbd47                 1/1       Running   0          1d
kube-scheduler-master            1/1       Running   0          9s
weave-net-cmk27                  2/2       Running   0          19s

而刚刚部署的 Weave 网络插件则在 kube-system 下面新建了一个名叫 weave-net-cmk27Pod,一般来说,这些 Pod 就是容器网络插件在每个节点上的控制组件。

Kubernetes 的支持的容器网络插件,使用的 CNI 的通用接口,当前开源的容器网络插件有

  • Flannel 这个采用应该比较多的
  • Calico
  • Canal
  • Romana

部署 Kubernetes Worker

Worker 节点的部署 和 Master 节点的运行的程序几乎相同, 都运行这 kubelet 组件,唯一的区别是 kubelet 启动后,Master 节点需要自动运行 kube-apiserverkube-schedulerkube-controller-manager 三个 Pod

执行部署Master时候生成的 kubeadm join 指令

> kubeadm join 10.168.0.2:6443 --token 00bwbx.uvnaa2ewjflwu1ry --discovery-token-ca-cert-hash sha256:00eb62a2a6020f94132e3fe1ab721349bbcd3e9b94da9654cfe15f2985ebd711

通过 Taint/Toleration 调整 Master 执行 Pod 的策略

默认情况下 Master 节点是不允许运行用户 Pod 的。而 Kubernetes 做到这一点,依靠的是 Kubernetes 的 Taint/Toleration 机制。

它的原理非常简单:一旦某个节点被加上了一个 Taint,即被“打上了污点”,那么所有 Pod 就都不能在这个节点上运行,因为 Kubernetes 的 Pod 都有“洁癖”。除非,有个别的 Pod 声明自己能“容忍”这个“污点”,即声明了 Toleration,它才可以在这个节点上运行。其中,为节点打上“污点”(Taint)的命令是:kubectl taint nodes node1 foo=bar:NoSchedule

默认情况下 Master 节点是不允许运行用户 Pod 的, 可以通过 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,而没有提供“值”。

当然,如果你就是想要一个单节点的 Kubernetes,删除这个 Taint 才是正确的选择:

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

部署 Dashboard 可视化插件

Web 页面展示也是一个很重要的方面,能可视化的查看集群的各种信息

> kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-rc6/aio/deploy/recommended.yaml


> kubectl get pods -n kube-system
kubernetes-dashboard-6948bdb78-f67xk   1/1       Running   0          1m

Dashboard 项目部署完成后,默认只能通过 Proxy 的方式在本地访问

部署 容器存储插件

Kubernetes 松耦合的设计,所以绝大多数存储项目都可以为 Kubernetes 提供持久化存储能力.

  • Ceph
  • GlusterFS
  • NFS

Rook 插件是基于 CephKubernetes 存储插件,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 pods -n rook-ceph-system
NAME                                  READY     STATUS    RESTARTS   AGE
rook-ceph-agent-7cv62                 1/1       Running   0          15s
rook-ceph-operator-78d498c68c-7fj72   1/1       Running   0          44s
rook-discover-2ctcv                   1/1       Running   0          15s

> kubectl get pods -n rook-ceph
NAME                   READY     STATUS    RESTARTS   AGE
rook-ceph-mon0-kxnzh   1/1       Running   0          13s
rook-ceph-mon1-7dn2t   1/1       Running   0          2s

这样,一个基于 Rook 持久化存储集群就以容器的方式运行起来了,而接下来在 Kubernetes 项目上创建的所有 Pod 就能够通过 Persistent Volume(PV)和 Persistent Volume Claim(PVC)的方式,在容器里挂载由 Ceph 提供的数据卷了。

comments powered by Disqus