0. 回顾Kubernetes架构
kubeadm使用简介
- apt-get install kubeadm( 宿主机上安装kubeadm,kubelet,kubectl)
- Kubeadm init
- 做一些列的检查工作,确认是否可以部署k8s,被称为Preflight checks
- 生成k8s对外提供服务所需的各种证书和对应的目录,注意,我们可以选择不让kubeadm生成这些证书,而是拷贝现有证书到/etc/kubernetes/pki/目录下
- 为其他组件生成访问kube-apiserver所需的配置文件,存储路径是/etc/kubernets/xxx.conf
- 为master组件,kube-apiserver,kube-controller-manager,kube-scheduler,生成pod配置文件(yaml文件),被保存在/etc/kubernetes/mainfests下
- 在4中节点上的kubelet启动后,通过static pod的方式加载4中目录下的pod yaml文件,并启动kube-apiserver这些master组件
- kubeadm会生成一个etcd的pod yaml文件,同样通过static pod的方式启动etcd,所以master组件的pod yaml文件如下
$ ls /etc/kubernetes/manifests/
etcd.yaml kube-apiserver.yaml kube-controller-manager.yaml kube-scheduler.yaml- 检查Locallhost:6443/healthz 这个健康检查url,等待master组件完全运行起来
- 为集群生成bootstrap token,为之后kubeadm join命令做验证
- 将master节点的重要信息,通过configmap的方式保存在etcd中,共后续安装Node节点使用
- 安装默认插件,k8s默认安装kube-proxy和dns,提供集群发现和dns功能。
- Kubeadm join
- 新的worker节点上kubeadm发起一次“不安全的”请求道kube-apiserver获取etcd中存储的cluster-info中的地址,端口,证书,bootstrap token扮演了安全验证的角色
- 通过证书建立起worker节点和master节点的 关系
1. 在所有节点上安装Docker和kubeadm
$ 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 docker.io kubeadm
通过这个步骤,kubeadm、kubelet、kubectl、kubernetes-cni这几个二进制文件都会被自动安装好。
2. 部署Kubernetes Master
2.1 编写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"
kubernetesVersion: "stable-1.11"
执行kubeadm init --config kubeadm.yaml, 稍等一会儿,部署完成后,kubeadm会生成一条指令,如下
kubeadm join 10.168.0.2:6443 --token 00bwbx.uvnaa2ewjflwu1ry --discovery-token-ca-cert-hash sha256:00eb62a2a6020f94132e3fe1ab721349bbcd3e9b94da9654cfe15f2985ebd711
记录下来上面这条指令,这是用来给这个master节点添加更多工作节点(worker)的命令。
通过kubectl describe node master和kubectl get pods -n kube-system查看到的是因为网络相关的配置没有进行导致nodenotready
2.2 安全文件配置
此外,Kubernetes默认需要加密方式访问。所以,需要把刚刚部署生成的Kubernetes集群的安全配置文件,保存到当前用户的.kube目录下,kubectl默认会使用这个目录下信息授权访问Kubernetes集群。
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
2.3 检查节点状态
- kubectl describe node master
$ 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
$ 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
可以看出,是CoreDNS、kube-controller-manager等依赖网络的Pod都处于Pending状态,即调度失败。
3. 部署容器网络插件
部署网络插件,以Weave为例,
$ kubectl apply -f https://git.io/weave-kube-1.6
部署完成后,重新kubectl get pods -n kube-system检查Pod的状态,全部都启动成功,保持running状态。
目前,Kubernetes支持容器网络插件,使用的是CNI的通用接口,也是当前容器网络的实施标准,市面上Flannel、Calico、Canal、Romana等一键部署项目都是通过CNI接口Kubernetes。
至此,Master节点部署完成,如果只需要一个Kubernetes,现在就可以使用了,但是默认情况下,Kubernetes的Master节点是不能运行用户Pod的,所以还需要额外做一个小操作,最后介绍。
4. 部署Kubernetes Worker节点
master节点和worker节点几乎是相同的,都运行着一个kubulet的组件。唯一的区别是Master节点会额外在kubeadm init过程中自动运行kube-apiserver, kube-scheduler, kube-controller-manager。
分两步执行部署:
- 在所有节点上执行第一小节“安装kubeadm和Docker”
- 执行部署Master节点是生成的kubeadm join指令
$ kubeadm join 10.168.0.2:6443 --token 00bwbx.uvnaa2ewjflwu1ry --discovery-token-ca-cert-hash sha256:00eb62a2a6020f94132e3fe1ab721349bbcd3e9b94da9654cfe15f2985ebd711
5. 通过Taint/Toleration调整Master执行Pod的策略
[规定]默认情况下Master节点是不运行Pod。
[实现方式]Taint/Toleration机制
Taint(污点):通过命令给node节点加上Taint之后,所有的Pod就不能再在这个node上运行了。---Pod有洁癖
Toleration(容忍):个别Pod可以特别声明自己可以容忍这个污点,那么就可以在对应打了污点的节点上运行。
[Taint使用方法]
$ kubectl taint nodes node1 foo=bar:NoSchedule
这样在node1上上城了一个键值对格式的Taint,其中里面的NoSchedule字段,意味着这个污点只会在调度新的Pod的时候产生作用,不会影响已经运行在Node1上的POD。
这么看来,给Node打上Taint的内容即foo=bar:NoSchedule部分还是有多种使用方法,这个还是要再研究下。
[Toleration使用方法]
在Pod对应的Yaml文件中加入字段:
apiVersion: v1
kind: Pod
...
spec:
tolerations:
- key: "foo"
operator: "Equal"
value: "bar"
effect: "NoSchedule"
6. 部署Dashboard可视化插件
安装可视化插件并查看对应Pod详情
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
$ kubectl get pods -n kube-system
kubernetes-dashboard-6948bdb78-f67xk 1/1 Running 0 1m
注意,dashboard是一个web service,1.7 版本之后dashboard项目部署完成后,只能通过Proxy在本地访问,需要用到Ingress。
7. 部署容器存储插件
容器持久化存储是解决容器的典型特征“无状态”的。
通过网络或者其他机制的远程数据卷,将其和容器中某个目录进行绑定挂载,进而使得在容器中创建的文件能够保存在远程存储服务器上、或以分布式的方式保存在多个节点上。
可用的,如Ceph,NFS,GlusterFS等,都可以为Kubernetes提供持久化存储能力。
8. 踩坑
- 离线安装kubelet
systemctl daemon-reload
systemctl start kubelet.service //启动失败,通过journalctl查看具体原因(systemctl起服务失败时候可以采用该日志定位方式)