kubeadm安装kubernetes1.13高可用及外置etcd

0. 核心组件

  • etcd 保存了整个集群的状态;
  • kube-apiserver 提供了资源操作的唯一入口,并提供认证、授权、访问控制、API 注册和发现等机制;
  • kube-controller-manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
  • kube-scheduler 负责资源的调度,按照预定的调度策略将 Pod 调度到相应的机器上;
  • kubelet 负责维持容器的生命周期,同时也负责 Volume(CVI)和网络(CNI)的管理;
  • Container runtime 负责镜像管理以及 Pod 和容器的真正运行(CRI),默认的容器运行时为 Docker
  • kube-proxy 负责为 Service 提供 cluster 内部的服务发现和负载均衡

0.1 插件

  • kube-dns 负责为整个集群提供 DNS 服务
  • Ingress Controller 为服务提供外网入口
  • Heapster 提供资源监控
  • Dashboard 提供 GUI
  • Federation 提供跨可用区的集群
  • Fluentd-elasticsearch 提供集群日志采集、存储与查询

1. 准备环境

Kubernetes 架构图

1551068252410

1.1 配置hosts

1
2
3
4
5
cat /etc/hosts
10.0.20.145 k8s-145
10.0.20.146 k8s-146
10.0.20.147 k8s-147
10.0.20.148 k8s-148

1.2 配置python

1
2
3
4
5
yum install epel-release -y
yum -y install sshpass
yum install python git python-pip -y
pip install pip --upgrade -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
pip install --no-cache-dir ansible -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com

1.3 配置ansible

1
2
git clone https://gitee.com/careyjike_173/k8s_install.git /etc/ansible
cd /etc/ansible
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
[deploy]
10.0.20.145
[etcd]
10.0.20.145 NODE_NAME=etcd1
10.0.20.146 NODE_NAME=etcd2
10.0.20.147 NODE_NAME=etcd3
[node]
10.0.20.148
[master]
10.0.20.145
# CA 证书相关参数
CA_EXPIRY="876000h"
CERT_EXPIRY="438000h"
# 二进制文件目录
bin_dir="/usr/local/kubernetes/bin"
# 证书目录
ca_dir="/usr/local/kubernetes/ssl"
# 部署目录
base_dir="/etc/ansible"

1.4 初始化系统

1
ansible-playbook 01init_os.yaml

2. 安装etcd

这里使用外置etcd

2.1 生成etcd证书

1
ansible-playbook 02certificate.yaml

2.2 配置etcd

1
ansible-playbook 03etcd.yaml

2.3 验证etcd群集

1
/usr/local/kubernetes/bin/etcdctl --endpoints=https://etcd1-ip:2379,https://etcd2-ip:2379,https://etcd3-ip:2379 --cert-file=/usr/local/kubernetes/ssl/etcd.pem --key-file=/usr/local/kubernetes/ssl/etcd-key.pem --ca-file=/usr/local/kubernetes/ssl/ca.pem cluster-health

3. 所有节点安装Docker/kubeadm/kubelet

Kubernetes默认CRI(容器运行时)为Docker,因此先安装Docker。

3.1 安装Docker

1
ansible-playbook 04docker.yaml

3.2 添加阿里云YUM软件源

1
2
3
4
5
6
7
8
9
$ cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

3.3 安装kubeadm,kubelet和kubectl

由于版本更新频繁,这里指定版本号部署:

1
2
3
$ yum install -y kubelet-1.13.3 // 这里指定版本应为依赖问题需分开yum安装
$ yum install -y kubeadm-1.13.3 kubectl-1.13.3
$ systemctl enable kubelet

4. 配置nginx

kube-apiserver高可用可以直接起多个节点,很多使用keepalivehaproxy来进行高可用配置,但是在大部分的公有云上无法使用vip。公有云上可以使用公有云提供的LoadBalance,这里我们使用nginx来代替

4.1 安装nginx

ngx stream core module

1
yum -y install nginx nginx-mod-stream
  • nginx stream 四层协议的转发、代理或者负载均衡

4.2 配置高可用kube-apiserver

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
stream {
log_format main '$remote_addr [$time_local]'
'$protocol $status $bytes_sent $bytes_received'
'$session_time';
server {
listen 7443;
proxy_pass kubeapi;
access_log /var/log/nginx/access.log main;
}
upstream kubeapi {
server 10.0.20.145:6443;
server 10.0.20.146:6443;
server 10.0.20.147:6443;
}
}

4. 部署Kubernetes Master

4.1 配置初始化参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
cat kubeadmin-config.yaml
apiVersion: kubeadm.k8s.io/v1beta1
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: "10.0.20.145"
bindPort: 6443
---
apiVersion: kubeadm.k8s.io/v1beta1
kind: ClusterConfiguration
kubernetesVersion: "v1.13.3" //指定要安装的kubernetes版本
controlPlaneEndpoint: "10.0.20.145:7443" // kube-apiserver群集代理ip,可使用nginx或keepalive,haproxy
networking:
serviceSubnet: "10.1.0.0/16"
podSubnet: "10.244.0.0/16"
imageRepository: registry.aliyuncs.com/google_containers // 默认拉取镜像地址k8s.gcr.io国内无法访问,指定阿里云镜像仓库地址
etcd: // 配置外置etcd
external:
endpoints:
- https://10.0.20.145:2379
- https://10.0.20.146:2379
- https://10.0.20.147:2379
caFile: /usr/local/kubernetes/ssl/ca.pem
certFile: /usr/local/kubernetes/ssl/etcd.pem
keyFile: /usr/local/kubernetes/ssl/etcd-key.pem

4.2 初始化master

1
$ kubeadm init --config=kubeadm-config.yaml

4.3 使用kubectl工具:

1
2
3
4
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
kubectl get nodes

4.4 手动复制证书到其他master节点

1
2
3
4
scp -r /etc/kubernetes/pki k8s-146:/etc/kubernetes/
scp -r /etc/kubernetes/pki k8s-147:/etc/kubernetes/
scp -r /etc/kubernetes/admin.conf k8s-146:/etc/kubernetes/admin.conf
scp -r /etc/kubernetes/admin.conf k8s-147:/etc/kubernetes/admin.conf

5. 安装Pod网络插件(CNI)

1
$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml

确保能够访问到quay.io这个registery。

6. 加入Kubernetes Master,Node

向集群添加新节点,执行在kubeadm init输出的kubeadm join命令:

6.1 添加master

  • --experimental-control-plane 创建一个master
1
kubeadm join 10.0.20.145:6443 --token 2xj72s.amdni1llci0t3mps --discovery-token-ca-cert-hash sha256:e051468f218d08e0edfaf090a54eb5747df3ff42cb77f930bcc4789aeffcd702 --experimental-control-plane --apiserver-advertise-address 10.0.20.145 # 指定本机IP

6.2 添加node

1
kubeadm join 10.0.20.145:6443 --token 2xj72s.amdni1llci0t3mps --discovery-token-ca-cert-hash sha256:e051468f218d08e0edfaf090a54eb5747df3ff42cb77f930bcc4789aeffcd702

7. 测试kubernetes集群

在Kubernetes集群中创建一个pod,验证是否正常运行:

1
2
3
$ kubectl create deployment nginx --image=nginx
$ kubectl expose deployment nginx --port=80 --type=NodePort
$ kubectl get pod,svc

访问地址:http://NodeIP:Port

8. 部署 Dashboard

1
$ kubectl apply -f kubernetes-dashboard.yaml

访问地址:http://NodeIP:30001

创建service account并绑定默认cluster-admin管理员集群角色:

1
2
3
$ kubectl create serviceaccount dashboard-admin -n kube-system
$ kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
$ kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')

使用输出的token登录Dashboard。

9. kubectl 命令自动补全

1
source <(kubectl completion bash)

如报错: bash: _get_comp_words_by_ref: 未找到命令
执行source /etc/profile.d/bash_completion.shsource /etc/bash_completion再执行source <(kubectl completion bash)即可

10. 问题记录

10.1 kubeadm token过期后加入新节点

默认token的有效期为24小时,当过期之后,该token就不可用了

  • 重新生成token
1
2
[root@k8s-12 ~]# kubeadm token create
tczji2.wpk4wx9utlu08snq
  • 获取ca证书sha256编码hash
1
2
[root@k8s-12 ~]# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
792a25d32c75c63e4da6586bcd05969da6d8284f23ee22612a3d4213b148ee0e
  • 节点加入集群

具体参考6.1
这里需要复制证书相关,具体参考4.4

1
kubeadm join 10.0.20.11:7443 --token tczji2.wpk4wx9utlu08snq --discovery-token-ca-cert-hash sha256:792a25d32c75c63e4da6586bcd05969da6d8284f23ee22612a3d4213b148ee0e --experimental-control-plane --apiserver-advertise-address 10.0.20.11

官方文档

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器