Kubernetes实践-部署
最近沉迷在 Kubernetes部署中不能自拔,作为初学者,基本上把可能踩的坑都踩了一遍,先分享一下怎么部署 Kubernetes 集群
首先,我们要知道 Kubernetes 是什么:
Kubernetes简称为k8s,它是 Google 开源的容器集群管理系统。在 Docker 技术的基础上,为容器化的应用提供部署运行、资源调度、服务发现和动态伸缩等一系列完整功能,提高了大规模容器集群管理的便捷性。
K8s 是一个完备的分布式系统支撑平台,具有完备的集群管理能力,多层次的安全防护和准入机制、多租户应用支撑能力、透明的服务注册和发现机制、內建负载均衡器、强大的故障发现和自我修复能力、服务滚动升级和在线扩容能力、可扩展的资源自动调度机制以及多粒度的资源配额管理能力。同时 K8s 提供完善的管理工具,涵盖了包括开发、部署测试、运维监控在内的各个环节。
安装
这个教程是对三台机器进行 k8s 部署,系统是Ubuntu 16.04.4 LTS。其中一台是 master ,其他两台是 worker。
安装 Docker
添加使用 HTTPS 传输的软件包以及 CA 证书
1 | $ sudo apt-get update |
添加软件源的 GPG 密钥
1 | $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - |
向 source.list 中添加 Docker 软件源
1 | $ sudo add-apt-repository \ |
安装指定版本
1 | $ apt-cache madison docker-ce |
在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,Ubuntu 系统上可以使用这套脚本安装:
1 | $ curl -fsSL get.docker.com -o get-docker.sh |
安装 kubeadm, kubelet 和 kubectl
官方源
1 | apt-get update && apt-get install -y apt-transport-https curl |
因为某些你懂的原因,要更换阿里源,并安装kubelet kubeadm kubectl:
1 | apt-get update && apt-get install -y apt-transport-https |
1 | 关闭swap |
使用kubeadm创建一个集群
使用 kubeadm 创建 k8s 集群其实还蛮简单,最大的困难是那堵墙,当我费了一整天把那堵墙问题解决后,发现 1.13.0 版本居然提供了中国特供的一个功能,所以把两种方法都写出来,供大家参考。
1.13.0 版本之前
查看kubeadm 会用到哪几个镜像:
1 | $ kubeadm config images list |
把得到的
1 | k8s.gcr.io/kube-apiserver:v1.13.0 |
写个批量脚本获取替换成阿里云镜像地址拉取images并打回标签
1 | images=( |
拉取完后kubeadm init
就可以完成 Kubernetes Master 的部署了
1.13.0版本之后
Kubenetes默认Registries地址是k8s.gcr.io,很明显,在国内并不能访问gcr.io,因此在kubeadm v1.13之前的版本,安装起来非常麻烦,但是在1.13版本中终于解决了国内的痛点,其增加了一个–image-repository参数,默认值是k8s.gcr.io,我们将其指定为国内镜像地址:registry.aliyuncs.com/google_containers,其它的就可以完全按照官方文档来愉快的玩耍了。
1 | $ kubeadm init \ |
kubeadm 会生成一行指令:
1 | kubeadm join 10.168.0.2:6443 --token 00bwbx.uvnaa2ewjflwu1ry --discovery-token-ca-cert-hash sha256:00eb62a2a6020f94132e3fe1ab721349bbcd3e9b94da9654cfe15f2985ebd711 |
并提示如下命令执行确保授权配置
1 | mkdir -p $HOME/.kube |
安装完后,
kubectl get 命令来查看当前唯一一个节点的状态了
1 | $ kubectl get nodes |
其中STATUS 是NotReady
我们通过kubectl describe 来查看这个节点(Node)对象的详细信息、状态和事件(Event)信息
1 | kubectl describe node {NAME} |
通过 kubectl describe 指令的输出,我们可以看到 NodeNotReady 的原因在于,我们尚未部署任何网络插件。
后面我们将专门讲关于部署插件。
另外,我们还可以通过 kubectl 检查这个节点上各个系统 Pod 的状态,其中,kube-system 是 Kubernetes
项目预留的系统 Pod 的工作空间(Namepsace,注意它并不是 Linux Namespace,它只是 Kubernetes 划分
不同工作空间的单位):
1 | $ kubectl get pods -n kube-system |
可以看到,CoreDNS、kube-controller-manager 等依赖于网络的 Pod 都处于 Pending 状态,即调度失败。这当然是符合预期的:因为这个 Master 节点的网络尚未就绪。
命令
获取端部节点
1 | $ kubectl get nodes |
查看node详细
1 | $ kubectl describe node iz94t4csjq4z |
查看全部pod
1 | $ kubectl get pods --all-namespaces |
通过namespaces获取pod
1 | $ kubectl get pods -n kube-system |
查看pod
1 | $ kubectl describe pod -n kube-system |
查看pod具体详情
1 | $ kubectl describe pod kubernetes-dashboard-767dc7d4d-mg5gw -n kube-system |
1 | $ kubectl edit cm coredns -n kube-system |
单节点配置( Master 隔离)
默认情况下 Master 节点是不允许运行用户 Pod 的,而 Kubernetes 做到这一点,依靠的是 是 Kubernetes 的 Taint/Toleration 机制。一旦某个节点被加上了一个 Taint,即被“打上了污点”那么所有 Pod 就都不能在这个节点上运行,因为 Kubernetes 的 Pod 都有“洁癖”。
如果你通过 kubectl describe 检查一下 Master 节点的 Taint 字段,就会有所发现了:
1 | $ kubectl describe node master |
可以看到,Master 节点默认被加上了node-role.kubernetes.io/master:NoSchedule这样一个“污点”,其中“键”是node-role.kubernetes.io/master,而没有提供“值”。
如果你就是想要一个单节点的 Kubernetes,删除个 Taint 才是正确的选择:
1 | $ kubectl taint nodes --all node-role.kubernetes.io/master- |
如上所示,我们在“node-role.io/master”这个键后面加上了一个短横线“-”,这个格式就意味着移除所有以“node-role.kubernetes.io/master”为键的 Taint。
这个步骤的配置最终使Master节点能允许运行用户pod,也是确保下面插件部署能正确运行。
到了这一步,一个基本完整的 Kubernetes 集群就完毕了。
部署插件
部署 Dashboard 可视化插件
kubernetes-dashboard先从国内镜像拉下来:
1 | $ docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kubernetes-dashboard-amd64:v1.10.0 |
打上kis.gcr.io的tag,这样执行Dashboard拉取的时候就直接本地拿pull下来的直接安装。
1 | 安装 |
安装后
1 | $ kubectl describe pod kubernetes-dashboard -n kube-system |
可查看Dashboard状态
部署网络插件
部署网络插件非常简单
因为这里的镜像来源不是kis.gcr.io,所以我们就不先拉取镜像下来.
1 | 安装 |
部署完成后,我们可以通过 kubectl get 重新检查Pod的状态:
1 | $ kubectl get pods -n kube-system |
部署容器存储插件
1 | 安装 |
加入工作节点
SSH到其他机器上,成为 root 用户(如:sudo su -),安装 kubeadm, kubelet and kubectl。
然后复制上面的运行kubeadm init命令时最后一句输出,并运行它的:
1 | $ kubeadm join --token <token> <master-ip>:<master-port> --discovery-token-ca-cert-hash sha256:<hash> |
这时候回到master 节点服务器,运行下面命令查看节点状态:
1 | $ kubectl get nodes |
NAME STATUS ROLES AGE VERSION
izuf6e4bl8eavupeu7q9a0z Ready
izuf6e4bl8eavupeu7q9a1z Ready master 75m v1.13.0
如果我们忘记了Master节点的加入token,可以使用如下命令来查看:
1 | $ kubeadm token list |
默认情况下,token的有效期是24小时,如果我们的token已经过期的话,可以使用以下命令重新生成:
1 | $ kubeadm token create |
如果我们也没有–discovery-token-ca-cert-hash的值,可以使用以下命令生成:
1 | $ openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //' |
至此一个简单的 k8s 集群部署就差不多了。
常见问题
Q1:
1 | 2018/11/05 04:04:18 [INFO] plugin/reload: Running configuration MD5 = f65c4821c8a9b7b5eb30fa4fbc167769 |
1 | 配置:--resolv-conf |
Q2:
1 | Unable to connect to the server: dial tcp 192.168.1.169:6443: connect: network is unreachable |
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
sudo swapoff -a
Q3:
1
2
3
4
5 [ERROR DirAvailable--etc-kubernetes-manifests]: /etc/kubernetes/manifests is not empty
[ERROR FileAvailable--etc-kubernetes-kubelet.conf]: /etc/kubernetes/kubelet.conf already exists
[ERROR Port-10250]: Port 10250 is in use
[ERROR FileAvailable--etc-kubernetes-pki-ca.crt]: /etc/kubernetes/pki/ca.crt already exists