使用kubespray自动化部署Kubernetes 1.14.1

Posted by Sunday on 2019-05-06

前言

部署Kubernetes除了手动方式外,还有诸如Kubeadm、Kubespray、Breeze、Rancher、kargo等多种自动化方式。工具没有好坏之分,能干事、效率高就行。这里,笔者仍使用Kubespray部署当前K8s最新版本(用着真的很贴身),可自动化部署HA集群、可灵活定制开发、高稳定性等。

环境说明

IP 主机名 角色
192.168.10.18 demo18 ansible-client(安装机)
192.168.10.101 k8s-master1 Master,Node,Etcd
192.168.10.102 k8s-master2 Master,Node,Etcd
192.168.10.103 k8s-master3 Master,Node,Etcd

Requirements

  • Ansible v2.7.8(或更新版本)和python-netaddr安装在将运行Ansible命令的机器上
  • Jinja 2.9(或更新版本)需要运行Ansible Playbooks
  • 目标服务器必须能够访问Internet才能获取docker镜像
  • 目标服务器配置为允许IPv4转发。
  • 您的ssh密钥必须复制到清单的所有服务器。
  • 为了避免在部署期间出现任何问题,您应该禁用防火墙。
  • 如果kubespray是从非root用户帐户运行的,则应在目标服务器中配置正确的权限提升方法。 然后应指定ansible_become标志或命令参数–become或-b。*

  • 硬件需求
    Master CPU >= 2
    Master 内存 >= 1500 MB
    Node 内存 >= 1024 MB

Kubernetes组件版本

  • Kubernetes v1.14.1
  • Etcd 3.2.26
  • Docker 18.06
  • Cri-O 1.11.5
  • Calico v3.4.0
  • Cilium 1.3.0
  • Contiv 1.2.1
  • Flannel 0.11.0
  • Kube-Router 0.2.5
  • Multus 3.1-autoconf
  • Weave 2.5.1
  • CoreDNS 1.5.0
  • Helm 2.13.1
  • Kubernetes Dashboard v1.10.1
  • Oracle OCI: v0.7.0

环境准备

目标机操作

关闭防火墙

1
systemctl stop firewalld && systemctl disable firewalld

升级内核至4.x

1
2
3
4
5
6
yum install epel-release -y
yum clean all
yum --enablerepo=elrepo-kernel install -y kernel-ml kernel-ml-devel

grub2-set-default 0
reboot

https://kubernetes.io/docs/setup/production-environment/tools/kubespray/

安装机操作

安装ansible

1
2
3
4
5
6
yum install -y epel-release
yum clean all
yum install -y python-pip ansible python36 python36-pip
pip3 install netaddr
pip3 install --upgrade jinja2
pip3 install pyyaml

安装机生成SSH公钥发送至所有目标机

1
2
3
ssh-keygen -t rsa
IP=(192.168.10.101 192.168.10.102 192.168.10.103)
for x in ${IP[*]}; do ssh-copy-id -i ~/.ssh/id_rsa.pub $x; done

配置kubespray

线上不使用master分支,建议切换至最新tag
https://kubespray.io

1
2
3
4
5
6
7
8
9
10
11
12
13
git clone https://github.com/kubernetes-incubator/kubespray.git
cd kubespray/
git checkout v2.10.0

# 安装requirements.txt中的依赖
sudo pip install -r requirements.txt

# 复制资产清单
cp -r inventory/sample inventory/mycluster

# 使用inventory_builder,初始化inventory文件
IPS=(192.168.10.101 192.168.10.102 192.168.10.103)
CONFIG_FILE=inventory/mycluster/hosts.yml python3 contrib/inventory_builder/inventory.py ${IPS[@]}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
cat inventory/mycluster/hosts.yml 

[all]
k8s-master1 ansible_host=192.168.10.101 ip=192.168.10.101
k8s-master2 ansible_host=192.168.10.102 ip=192.168.10.102
k8s-master3 ansible_host=192.168.10.103 ip=192.168.10.103

[kube-master]
k8s-master1
k8s-master2
k8s-master3

[kube-node]
k8s-master1
k8s-master2
k8s-master3

[etcd]
k8s-master1
k8s-master2
k8s-master3

[k8s-cluster:children]
kube-node
kube-master

[calico-rr]

稍加修改主机名,master1-3,安装过程中会自动修改主机名和node master名称。
生产环境,master和etcd 请配置在不同节点。这里是测试环境,因硬件资源紧张就将master和etcd部署在相同节点了。

查看或修改默认参数

1
2
3
4
5
6
7
8
cat inventory/mycluster/group_vars/k8s-cluster/k8s-cluster.yml

kube_version: v1.14.1
kube_network_plugin: calico
kube_service_addresses: 10.233.0.0/18
ube_pods_subnet: 10.233.64.0/18
kube_proxy_mode: ipvs
...

修改代理

由于国内因素,默认无法下载镜像。
方法1.替换镜像
将grc.io和quay.io的镜像上传到阿里云
或使用Azure中国 GCR Proxy
gcr.azk8s.cn/google_containers

1
2
3
4
5
6
7
8
9
10
11
cd role/download/defaults
cp main.yml main.yaml.1
sed -i 's/k8s\.gcr\.io/{{ k8s_gcr_io_repo }}/g' main.yml
sed -i 's/gcr\.io/{{ gcr_io_repo }}/g' main.yml

cd inventory/mycluster/group_vars/k8s-cluster

#kube_image_repo: "gcr.io/google-containers"
kube_image_repo: "gcr.azk8s.cn/google_containers"
gcr_io_repo: "gcr.azk8s.cn/google_containers"
k8s_gcr_io_repo: "gcr.azk8s.cn/google_containers"

方法2.设置代理

1
2
3
cat inventory/mycluster/group_vars/all/all.yml
http_proxy: "http://192.168.10.251:1080"
https_proxy: "http://192.168.10.251:1080"

调优

docker源 加速
默认从docker官方源安装docker,速度太慢了,我们更换为国内源。
编辑 追加如下内容

1
2
3
4
5
6
7
8
9
10
11
12
vim inventory/mycluster/group_vars/k8s-cluster/k8s-cluster.yml
# CentOS/RedHat docker-ce repo
docker_rh_repo_base_url: 'https://mirrors.aliyun.com/docker-ce/linux/centos/7/$basearch/stable'
docker_rh_repo_gpgkey: 'https://mirrors.aliyun.com/docker-ce/linux/centos/gpg'

# dockerproject repo
dockerproject_rh_repo_base_url: 'http://mirror.azure.cn/docker-engine/yum/repo/main/centos/7/'
dockerproject_rh_repo_gpgkey: 'http://mirror.azure.cn/docker-engine/yum/gpg'

# CentOS/RedHat Extras repo
extras_rh_repo_base_url: "https://mirrors.aliyun.com/centos//$releasever/extras/$basearch/"
extras_rh_repo_gpgkey: "https://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7"

生效会覆盖 roles/container-engine/docker/defaults/main.yml 官方源

部署集群

1
ansible-playbook -i inventory/mycluster/hosts.yml cluster.yml -b -v

验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
kubectl get nodes

NAME STATUS ROLES AGE VERSION
master1 Ready master 24h v1.14.1
master2 Ready master 24h v1.14.1
master3 Ready master 24h v1.14.1

kubectl get pods -n kube-system

NAME READY STATUS RESTARTS AGE
calico-kube-controllers-5bb9cf8fff-dkhpq 1/1 Running 2 24h
calico-node-76cns 1/1 Running 2 24h
calico-node-rkwwz 1/1 Running 1 24h
calico-node-xxw8r 1/1 Running 2 24h
coredns-7646874c97-4xznl 1/1 Running 0 23h
coredns-7646874c97-82ggv 1/1 Running 0 24h
dns-autoscaler-56c969bdb8-9rtft 1/1 Running 2 24h
kube-apiserver-master1 1/1 Running 3 24h
kube-apiserver-master2 1/1 Running 3 24h
kube-apiserver-master3 1/1 Running 2 24h
kube-controller-manager-master1 1/1 Running 2 24h
kube-controller-manager-master2 1/1 Running 1 24h
kube-controller-manager-master3 1/1 Running 2 24h
kube-proxy-mbh2k 1/1 Running 1 24h
kube-proxy-xck9h 1/1 Running 2 24h
kube-proxy-xr9rq 1/1 Running 2 24h
kube-scheduler-master1 1/1 Running 2 24h
kube-scheduler-master2 1/1 Running 1 24h
kube-scheduler-master3 1/1 Running 2 24h
kubernetes-dashboard-6c7466966c-z2ttd 1/1 Running 2 24h
nodelocaldns-hrjrh 1/1 Running 0 24h
nodelocaldns-svr46 1/1 Running 0 24h
nodelocaldns-w6fkp 1/1 Running 0 24h

部署测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 创建一个nginx
kubectl create nginx --image=nginx:1.7.9 --port=80

# 暴露nginx端口
kubectl expose deployment nginx --type=NodePort

# 查看nginx服务详情
kubectl get svc nginx

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx NodePort 10.233.22.159 <none> 80:31758/TCP 5m58s

# 访问测试
curl 192.168.10.101:31758

高可用

etcd高可用

etcd本身就支持集群模式,所以啥都不用考虑,只要保证节点数量足够,升级备份之类的事情,kubespray已经帮你做了。

由于etcd采用Raft一致性算法,集群规模最好不要超过9个,推荐3,5,7,9个数量。具体看集群规模。如果性能不够,宁可多分配资源,也最好不要超过9个。

这里能选择偶数个节点吗? 最好不要这样。原因有二:

  • 偶数个节点集群不可用风险更高,表现在选主过程中,有较大概率或等额选票,从而触发下一轮选举。
  • 偶数个节点集群在某些网络分割的场景下无法正常工作。试想,当网络分割发生后,将集群节点对半分割开。此时集群将无法工作。按照RAFT协议,此时集群写操作无法使得大多数节点同意,从而导致写失败,集群无法正常工作。

kube-apiserver 高可用
https://kubespray.io/#/docs/ha-mode
haproxy

1
2
3
4
5
6
7
8
9
10
11
12
yum install -y haproxy keepalived
vim /etc/haproxy/haproxy.cfg
listen kubernetes-apiserver-https
bind *:8443
option ssl-hello-chk
mode tcp
timeout client 3h
timeout server 3h
server master1 192.168.10.81:6443
server master2 192.168.10.82:6443
server master3 192.168.10.83:6443
balance roundrobin

keepalived

1
2


维护命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
如果需要扩容Work节点,则修改hosts.yml文件,增加新增的机器信息 执行命令:
ansible-playbook -i inventory/mycluster/hosts.yml scale.yml -b -v -k

将hosts.yml文件中的master和etcd的机器增加到多台,执行部署命令
ansible-playbook -i inventory/mycluster/hosts.yml cluster.yml -b -vvv

刪除节点,如果不指定节点就是刪除整个集群:
ansible-playbook -i inventory/mycluster/hosts.yml remove-node.yml -b -v

卸载执行命令:
ansible-playbook -i inventory/mycluster/hosts.yml reset.yml -b -vvv

升级K8s集群,选择对应的k8s版本信息,执行升级命令。涉及文件为upgrade-cluster.yml。
ansible-playbook upgrade-cluster.yml -b -i inventory/mycluster/hosts.yml -e kube_version=vX.XX.XX -vvv
1
2
3
kubectl get nodes
kubectl get pods --all-namespaces
ipvsadm -L -n

链接

使用kubespray在国内安装Kubernetes
https://kubespray.io