How to deploy Kubernetes with Kubespray


本文介绍如何通过kuberpray部署kubernetes集群。

准备工作

准备server

我们需要按照既定需求准备server,并且要保证部署服务器要能够免密登陆kubernetes组件所在的server。

这里我们单独准备了一个部署服务器,并且将下面提到的harbor和梯子等都部署在了这个服务器上。

部署harbor

kubespray中使用的一部分镜像来自于gcr.io,墙内无法访问,我们需要部署一个本地的harbor来解决这个问题。

部署harbor过程,略。

架梯子

架梯子,略。

这里介绍一下如何设置docker连接代理,这里我使用ss搭建的代理。注意排除本地repodockerhub,这样才能保证同时可以访问本地repogcr.io

1
2
3
4
5
6
7
8
ss -antlp |grep sslocal
LISTEN0      128                               0.0.0.0:1080        0.0.0.0:*     users:(("sslocal",pid=6598,fd=3))

cat /lib/systemd/system/docker.service.d/http-proxy.conf    
[Service]
Environment="HTTP_PROXY=socks5://192.168.0.90:1080" "HTTPS_PROXY=socks5://192.168.0.90:1080" "NO_PROXY=localhost,127.0.0.1,192.168.0.90,192.168.0.90:80,hub.docker.com"

systemctl daemon-reload; systemctl restart docker

下载kubespray代码,并切换到期望的分支

1
2
3
4
5
git clone https://github.com/kubernetes-incubator/kubespray.git
cd kubespray
git branch -a
# 查看github中的release信息确定版本,这里我们选择kubernetes 1.9.x对应的kubespray版本
git checkout -b v2.5.0 v2.5.0

准备镜像

接下来我们需要处理镜像了,因为一部分镜像在国内无法访问,这部分镜像我们可以通过grep 'gcr.io' -r来确定。

1
2
3
4
5
6
7
# 我们可以看到镜像与版本相关的变量主要在roles/download/defaults/main.yml与roles/kubernetes-apps/ansible/defaults/main.yml中
grep 'gcr.io' -r
# 我们需要将这些镜像一次pull下来--当然这需要你自己准备梯子--然后再上传到我们的harbor
# 以hyperkube为例
docker pull gcr.io/google-containers/hyperkube:v1.9.5
docker tag gcr.io/google-containers/hyperkube:v1.9.5 {harbor_ip}:{harbor_port}/google-containers/hyperkube:v1.9.5
docker push {harbor_ip}:{harbor_port}/google-containers/hyperkube:v1.9.5

同时,kubespray中关于镜像的变量也要做相应的修改–把gcr.io修改为我们harbor的地址。

1
2
# 执行前请确认gcr.io只在镜像地址的变量中出现
find . -name "*.yml" -exec sed -i 's/gcr.io/{harbor_ip}:{harbor_port}/g' {} \;

修改源码中的配置

有一些事情我们需要通过修改源码中的配置文件来完成,比如:添加docker的insecure-registry,添加kubernetes的feature-gates属性。 举例的这两个变量都出现在了roles/kubespray-defaults/defaults/main.yaml中,我们按照需求修改即可。

 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
# 这里我们开启了DevicePlugins的特性
# 修改./roles/kubespray-defaults/defaults/main.yaml
## List of key=value pairs that describe feature gates for
## the k8s cluster.
kube_feature_gates:
  - "Initializers={{ istio_enabled | string }}"
  - "PersistentLocalVolumes={{ local_volume_provisioner_enabled | string }}"
  - "VolumeScheduling={{ local_volume_provisioner_enabled | string }}"
  - "MountPropagation={{ local_volume_provisioner_enabled | string }}"
  - "DevicePlugins=true"

# 修改docker选项,使其能够支持http协议的docker registry
# 我们可以看到设置中原来已经有了一个insecure-registry选项,这是为了集群中自带的harbor准备的,而我们为了能够使用harbor来下载gcr.io中的镜像,所以需要再添加一个
# 修改./roles/kubespray-defaults/defaults/main.yaml
## A string of extra options to pass to the docker daemon.
## This string should be exactly as you wish it to appear.
## An obvious use case is allowing insecure-registry access
## to self hosted registries like so:
docker_options: "--insecure-registry={{ kube_service_addresses }} --insecure-registry={harbor_ip}:{harbor_port} --graph={{ docker_daemon_graph }} {{ docker_log_opts }}"

# 为了部署prometheus,并使其能通过kubelet收集节点信息,我们需要开启kubelet的webhook认证
# 修改./roles/kubespray-defaults/defaults/main.yaml
# When enabled, API bearer tokens (including service account tokens) can be used to authenticate to the kubelet’s HTTPS endpoint
kubelet_authentication_token_webhook: true

# When enabled, access to the kubelet API requires authorization by delegation to the API server
kubelet_authorization_mode_webhook: true

进行部署

前面的铺垫完成后,我们就可以按照kubespray项目readme的描述来向下进行。这里我们不做其他额外的操作。

 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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# 复制inventory文件
cp -rfp inventory/sample inventory/mycluster

# 生成host.ini
declare -a IPS=(10.10.1.3 10.10.1.4 10.10.1.5)
CONFIG_FILE=inventory/mycluster/hosts.ini python3 contrib/inventory_builder/inventory.py ${IPS[@]}

# readme中使用inventory.py自动生成了一个hosts.ini,如果对结果不满意,我们可以进行一些修改
vim inventory/mycluster/hosts.ini
cat inventory/mycluster/hosts.ini
# ## Configure 'ip' variable to bind kubernetes services on a
# ## different ip than the default iface
# node1 ansible_ssh_host=95.54.0.12  # ip=10.3.0.1
# node2 ansible_ssh_host=95.54.0.13  # ip=10.3.0.2
# node3 ansible_ssh_host=95.54.0.14  # ip=10.3.0.3
# node4 ansible_ssh_host=95.54.0.15  # ip=10.3.0.4
# node5 ansible_ssh_host=95.54.0.16  # ip=10.3.0.5
# node6 ansible_ssh_host=95.54.0.17  # ip=10.3.0.6
[all]
node1 ansible_ssh_host=192.168.250.91 ip=192.168.250.91
node2 ansible_ssh_host=192.168.250.92 ip=192.168.250.92
node3 ansible_ssh_host=192.168.250.93 ip=192.168.250.93

# ## configure a bastion host if your nodes are not directly reachable
# bastion ansible_ssh_host=x.x.x.x

[kube-master]
node1
node2

[etcd]
node1
node2
node3

[kube-node]
node1
node2
node3

[kube-ingress]
node1

[k8s-cluster:children]
kube-master
kube-node
kube-ingress
# end of cat command

# 安装python依赖
pip install -r requirements.txt

# 安装kubernetes
ansible-playbook -i inventory/mycluster/hosts.ini cluster.yml -b -vvv

完成

完成后我们便可以登陆到kubernetes集群中探索了。