Kubernetes 集群部署需要安装的组件东西很多, 过程复杂, 对服务器环境要求很苛刻, 最好是能连外网的环境下安装, 有些组件还需要连 google 服务器下载, 这一点一般很难满足, 因此最好是能提前下载好准备的就尽量下载好.
Kubernetes 集群部署要求
服务器必须是 CentOS 7.2 及以上
Kubernetes 采用 1.12 版本
- Docker-ce v17.03.2
- Etcd 3.2.9
- Flanneld v0.7.0-amd64
TLS 认证通信 (所有组件, 如 etcd,kubernetes master 和 node)
RBAC 授权
kubedns,dashboard,heapster 等插件
harbor, 使用 nfs 后端存储
......
部署方式
Minikube 快速搭建单节点 Kubenetes 集群的工具, 只能用作学习实践.
kubeadm 是 Kubernetes 官方提供的用于快速安装 Kubernetes 集群的工具
使用 Rancher 部署 K8S 集群, 布署在 Docker 环境中, 方便快捷.
Ansible 脚本安装 K8S 集群
如果对 Rancher 吃不透的话还是推荐使用 Ansible 脚本安装 K8S 集群, Ansible 脚本将安装的流程都封装到了脚本里, 只需更改安装主机服务器地址和环境就能实现一键布署.
推荐使用 GitHub 上的 https://github.com/gjmzj/kubeasz , 能简化很多流程.
kubeasz 致力于提供快速部署高可用 k8s 集群的工具, 并且也努力成为 k8s 实践, 使用的参考书; 基于二进制方式部署和利用 ansible-playbook 实现自动化: 即提供一键安装脚本, 也可以分步执行安装各个组件, 同时讲解每一步主要参数配置和注意事项.
集群特性: TLS 双向认证, RBAC 授权, 多 Master 高可用, 支持 Network Policy, 备份恢复
布署关键点
为了初次安装顺利, 关闭防火墙.
确保各节点时区设置一致, 时间同步.
无法访问公网情况下, 请下载离线 docker 镜像完成集群安装.
从国内下载 docker 官方仓库镜像非常缓慢, 所以对于 k8s 集群来说配置镜像加速非常重要, 配置 /etc/docker/daemon.JSON, 若访问不了外网就要配置局域网的镜像仓库地址.
docker 要开启 docker 远程 API 修改 docker 配置文件 docker.service 在 ExecStart 这一行后面加上 -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
docker 从 1.13 版本开始, 将 iptables 的 filter 表的 FORWARD 链的默认策略设置为 DROP, 从而导致 ping 其它 Node 上的 Pod IP 失败, 因此必须在 filter 表的 FORWARD 链增加一条默认允许规则 iptables -I FORWARD -s 0.0.0.0/0 -j ACCEPT
后续 calico 网络, kube-proxy 等将大量使用 iptables 规则, 要维护好服务器本身的 iptables 规则.
网络组件
Kubernetes 中网络是最复杂的, 虽然从架构图上看是很清楚的, 但实际操作起来还是到处报错, 涉及到防火墙, iptables 规则, 服务器间的网络, 网络组件的配置, 容器与容器间的访问, 容器与服务器的互相访问等等.
推荐 flannel , 这里参考其它博文着重介绍下:
Flannel 的功能是让集群中的不同节点主机创建的 Docker 容器都具有全集群唯一的虚拟 IP 地址.
Flannel 实质上是一种 "覆盖网络 (overlay network)", 也就是将 TCP 数据包装在另一种网络包里面进行路由转发和通信, Flannel 的设计目的就是为集群中的所有节点重新规划 IP 地址的使用规则, 从而使得不同节点上的容器能够获得 "同属一个内网" 且 "不重复的"IP 地址, 并让属于不同节点上的容器能够直接通过内网 IP 通信.
默认的节点间数据通信方式是 UDP 转发, 在 Flannel 的 GitHub 页面有如下的一张原理图:
1. 数据从源容器中发出后, 经由所在主机的 docker0 虚拟网卡转发到 flannel0 虚拟网卡, 这是个 P2P 的虚拟网卡, flanneld 服务监听在网卡的另外一端. Flannel 也是通过修改 Node 的路由表实现这个效果的.
2. 源主机的 flanneld 服务将原本的数据内容 UDP 封装后根据自己的路由表投递给目的节点的 flanneld 服务, 数据到达以后被解包, 然后直接进入目的节点的 flannel0 虚拟网卡, 然后被转发到目的主机的 docker0 虚拟网卡, 最后就像本机容器通信一样由 docker0 路由到达目标容器.
3. 使每个结点上的容器分配的地址不冲突. Flannel 通过 Etcd 分配了每个节点可用的 IP 地址段后, 再修改 Docker 的启动参数."--bip=X.X.X.X/X" 这个参数, 它限制了所在节点容器获得的 IP 范围.
flannel 使用 vxlan 技术为各节点创建一个可以互通的 Pod 网络, 使用的端口为 UDP 8472, 需要开放该端口.
kube-apiserver 的高可用
keepalived+haproxy 配置多个后端真实 kube-apiserver 的 endpoints, 并启用存活监测后端 kube-apiserver, 保证 kube-apiserver 的高可用.
dashboard
dashboard 1.7 以后默认开启了自带的登陆验证机制, 1.7 开始, dashboard 只允许通过 https 访问, 如果使用 kube proxy 则必须监听 localhost 或 127.0.0.1, 对于 NodePort 没有这个限制, 但是仅建议在开发环境中使用.
对于不满足这些条件的登录访问, 在登录成功后浏览器不跳转, 始终停在登录界面.
参考:
kubernetes-dashboard 服务暴露了 NodePort, 可以使用
https://NodeIP:NodePort
地址访问 dashboard;
通过 kube-apiserver 访问 dashboard;
通过 kubectl proxy 访问 dashboard:
Ingress
Ingress 其实就是从 kuberenets 集群外部访问集群的一个入口, 将外部的请求转发到集群内不同的 Service 上, 其实就相当于 nginx,apache 等负载均衡代理服务器, 再加上一个规则定义, 路由信息的刷新需要靠 Ingress controller 来提供.
Ingress controller 可以理解为一个监听器, 通过不断地与 kube-apiserver 打交道, 实时的感知后端 service,pod 等的变化, 当得到这些变化信息后, Ingress controller 再结合 Ingress 的配置, 更新反向代理负载均衡器, 达到服务发现的作用. 其实这点和服务发现工具 consul 的 consul-template 非常类似.
未配置 ingress:
集群外部 -> NodePort -> K8S Service
配置了 ingress:
集群外部 -> Ingress -> K8S Service
注意: ingress 本身也需要部署 Ingress controller 时暴露 NodePort 让外部访问; 如果你集群支持, 可以方便地使用 LoadBalancer 地址暴露 ingress 服务.
Traefik 提供了一个简单好用 Ingress controller, 是一款开源的反向代理与负载均衡工具. 它最大的优点是能够与常见的微服务系统直接整合, 可以实现自动化动态配置.
如果采用 Rancher 部署会有从 k8s.gcr.io 拉取镜像失败问题
新版本的 Kubernetes 在安装部署中, 需要从 k8s.grc.io 仓库中拉取所需镜像文件, 但由于国内网络防火墙问题导致无法正常拉取.
解决方案
docker.io 仓库对 google 的容器做了镜像, 可以通过下列命令下拉取相关镜像:
- docker pull mirrorgooglecontainers/kube-apiserver:v1.12.0
- docker pull mirrorgooglecontainers/kube-controller-manager:v1.12.0
- docker pull mirrorgooglecontainers/kube-scheduler:v1.12.0
- docker pull mirrorgooglecontainers/kube-proxy:v1.12.0
- docker pull mirrorgooglecontainers/pause:3.1
- docker pull mirrorgooglecontainers/etcd:3.2.24
- docker pull coredns/coredns:1.2.2
- docker tag docker.io/mirrorgooglecontainers/kube-proxy:v1.12.0 k8s.gcr.io/kube-proxy:v1.12.0
- docker tag docker.io/mirrorgooglecontainers/kube-scheduler:v1.12.0 k8s.gcr.io/kube-scheduler:v1.12.0
- docker tag docker.io/mirrorgooglecontainers/kube-apiserver:v1.12.0 k8s.gcr.io/kube-apiserver:v1.12.0
- docker tag docker.io/mirrorgooglecontainers/kube-controller-manager:v1.12.0 k8s.gcr.io/kube-controller-manager:v1.12.0
- docker tag docker.io/mirrorgooglecontainers/etcd:3.2.24 k8s.gcr.io/etcd:3.2.24
- docker tag docker.io/mirrorgooglecontainers/pause:3.1 k8s.gcr.io/pause:3.1
- docker tag docker.io/coredns/coredns:1.2.2 k8s.gcr.io/coredns:1.2.2
- $ kubectl logs -f pods/heapster-2882613285-58d9r -n kube-system
- E0630 17:23:47.339987 1 reflector.go:203] k8s.io/heapster/metrics/sources/kubelet/kubelet.go:342: Failed to list *API.Node: Get http://kubernetes.default/api/v1/nodes?resourceVersion=0: dial tcp: i/o timeout E0630 17:23:47.340274 1 reflector.go:203] k8s.io/heapster/metrics/heapster.go:319: Failed to list *API.Pod: Get http://kubernetes.default/api/v1/pods?resourceVersion=0: dial tcp: i/o timeout E0630 17:23:47.340498 1 reflector.go:203] k8s.io/heapster/metrics/processors/namespace_based_enricher.go:84: Failed to list *API.Namespace: Get http://kubernetes.default/api/v1/namespaces?resourceVersion=0: dial tcp: lookup kubernetes.default on 10.254.0.2:53: dial udp 10.254.0.2:53: i/o timeout E0630 17:23:47.340563 1 reflector.go:203] k8s.io/heapster/metrics/heapster.go:327: Failed to list *API.Node: Get http://kubernetes.default/api/v1/nodes?resourceVersion=0: dial tcp: lookup kubernetes.default on 10.254.0.2:53: dial udp 10.254.0.2:53: i/o timeout E0630 17:23:47.340623 1 reflector.go:203] k8s.io/heapster/metrics/processors/node_autoscaling_enricher.go Failed to list *API.Node: Get http://kubernetes.default/api/v1/nodes?resourceVersion=0: dial tcp: lookup kubernetes.default on 10.254.0.2:53: dial udp 10.254.0.2:53: i/o timeout E0630 17:23:55.014414 1 influxdb.go:150] Failed to create infuxdb: failed to ping InfluxDB server at "monitoring-influxdb:8086" - Get http://monitoring-influxdb:8086/ping: dial tcp: lookup monitoring-influxdb on 10.254.0.2:53: read udp 172.30.45.4:48955->10.254.0.2:53: i/o timeout`
- $ curl my-nginx.nx.svc.cluster.local
- curl: (7) Failed connect to my-nginx.nx.svc.cluster.local:80; No route to host
- $ iptables --flush && iptables -tnat --flush
- $ systemctl restart docker
来源: https://www.cnblogs.com/zhangs1986/p/10749721.html