本文主要介绍了通过kubeadm部署3master节点高可用k8s 1.17.3集群
更新于 2021-03-28
集群规划
主机名 |
IP地址 |
用途 |
SCA-LUM700011 |
10.8.138.8 |
nginx+nfs+运维节点 |
SCA-LUM700007 |
10.8.138.5 |
master-1 |
SCA-LUM700008 |
10.8.138.6 |
Master-2 |
SCA-LUM700012 |
10.8.138.10 |
Master-3 |
SCA-LUM700013 |
10.8.138.9 |
Node-1 |
SCA-LUM700014 |
10.8.138.11 |
node-2 |
操作系统centos7.6
,前端还有一个elb,地址为10.8.138.12
,代理master的apiserver。kube-proxy使用ipvs
模式,集群使用1.17.3
版本
安装工具
内核优化
部署前准备
安装基础服务
添加yum源
1 2 3 4 5 6 7 8 9 10 11 12
| 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=0 repo_gpgcheck=0 gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF
ansible cluster -m copy -a 'src=/etc/yum.repos.d/kubernetes.repo dest=/etc/yum.repos.d/kubernetes.repo'
|
安装kubelet、kubectl、kubeadm
这里安装的是1.17.3
版本:
1 2 3 4 5 6 7 8
| ansible cluster -m shell -a 'yum install -y kubelet-1.17.3 kubeadm-1.17.3 kubectl-1.17.3'
ansible cluster -m shell -a 'ls /usr/bin/kube*'
ansible cluster -m shell -a 'systemctl enable kubelet'
|
部署master节点
这一步在任意一个master上执行,这里我在master1
上执行。需要配置下kubeadm的相关参数。
配置kubeadm参数
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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| cat > kubeadm-config.yaml << EOF apiVersion: kubeadm.k8s.io/v1beta2 kind: InitConfiguration localAPIEndpoint: advertiseAddress: 0.0.0.0 bindPort: 6443 nodeRegistration: criSocket: /var/run/dockershim.sock taints: - effect: NoSchedule key: node-role.kubernetes.io/master kubeletExtraArgs: cgroup-driver: "systemd" ignorePreflightErrors: - IsPrivilegedUser --- apiVersion: kubeadm.k8s.io/v1beta2 kind: ClusterConfiguration controlPlaneEndpoint: 10.8.138.12:6443 certificatesDir: /etc/kubernetes/pki clusterName: kubernetes apiServer: timeoutForControlPlane: 5m0s extraArgs: authorization-mode: "Node,RBAC" certSANs: - "10.8.138.12" - "14.116.177.22" - "kubernetes" - "kubernetes.default" - "kubernetes.default.svc" - "kubernetes.default.svc.cluster" - "kubernetes.default.svc.cluster.local" controllerManager: extraArgs: "node-cidr-mask-size": "20" scheduler: extraArgs: address: "0.0.0.0" dns: type: CoreDNS etcd: local: dataDir: /var/lib/etcd # extraArgs: # listen-client-urls: "http://10.100.0.1:2379" # serverCertSANs: # serverCertSANs: # - "localhost" # - "127.0.0.1" # peerCertSANs: # - "localhost" # - "127.0.0.1" imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers kubernetesVersion: v1.17.3 networking: dnsDomain: cluster.local serviceSubnet: 172.24.0.0/16 podSubnet: 172.21.0.0/16 --- apiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration bindAddress: 0.0.0.0 #clusterCIDR: mode: ipvs # 定义代理模式: userspace、 iptables 或 ipvs 。默认使用 iptables ,大集群建议使用 ipvs。 ipvs: scheduler: lc syncPeriod: 30s minSyncPeriod: 5s tcpTimeout: 0s tcpFinTimeout: 0s udpTimeout: 0s --- apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration EOF
|
- 其中
10.8.138.12
为我前端slb的IP地址,代理后端三个master节点的6443;
- 根据实际情况在
certSANs
中添加IP和域名;
- 注意修改其中的kubernetes的版本,以及ipvs模式的调度算法(这里我使用的是lc)
验证配置
下面的命令可以验证配置是否有误,并不会真正执行:
1
| kubeadm init --config=kubeadm-config.yaml --upload-certs --dry-run
|
创建集群
1 2
| kubeadm init --config=kubeadm-config.yaml --upload-certs
|
执行成功的话,会出现下面的信息:

从上边可以看出,添加master节点和node节点就可以在对应服务器上执行下面的命令:
1 2 3 4 5 6 7 8
| # 添加master kubeadm join 10.8.138.12:6443 --token z9ibq2.s5ttzyxvc49mep02 \ --discovery-token-ca-cert-hash sha256:71a025d1a18f9ec0f4c16ab771b2d01674ce9921316c87e0bdfd162d53f8524e \ --control-plane --certificate-key d708ea62b465ecfd667fa807eb6a0cc7babbb4969a3bb9256f13543a2ddfe20c # 添加node节点 kubeadm join 10.8.138.12:6443 --token z9ibq2.s5ttzyxvc49mep02 \ --discovery-token-ca-cert-hash sha256:71a025d1a18f9ec0f4c16ab771b2d01674ce9921316c87e0bdfd162d53f8524e
|
命令中的token有两个小时时效,时效后需要重新获取
添加其他的master节点
在剩下的两个master节点SCA-LUM700008
和SCA-LUM700012
执行下面的命令:
1 2 3
| kubeadm join 10.8.138.12:6443 --token z9ibq2.s5ttzyxvc49mep02 \ --discovery-token-ca-cert-hash sha256:71a025d1a18f9ec0f4c16ab771b2d01674ce9921316c87e0bdfd162d53f8524e \ --control-plane --certificate-key d708ea62b465ecfd667fa807eb6a0cc7babbb4969a3bb9256f13543a2ddfe20c
|
不需要拷贝kubeadm-config.yaml文件,会通过第一个apiserver去配置信息;
设置kubectl
1 2 3 4 5
| ansible master -m shell -a 'echo "source <(kubectl completion bash)" >> ~/.bashrc'
cp /etc/kubernetes/admin.conf /root/.kube/config
|
验证master部署情况
1 2 3 4 5
| kubectl get node --kubeconfig /etc/kubernetes/admin.conf
kubectl get pod --all-namespaces --kubeconfig /etc/kubernetes/admin.conf
|

这里有些pod没有启动是正常的,因为集群还没部署完成。
确认kubeproxy开启了ipvs
首先查看网卡信息,多了一个kube-ipvs0网卡:
查看ipvs规则:
部署etcd
更新etcd配置
更新后会自动重启服务:
1 2 3 4
| ansible master -m shell -a 'sed -i "/--initial-cluster=/c\ - --initial-cluster=sca-lum700012=https://10.8.138.10:2380,sca-lum700007=https://10.8.138.5:2380,sca-lum700008=https://10.8.138.6:2380" /etc/kubernetes/manifests/etcd.yaml'
ansible master -m shell -a 'sed -i "/- --etcd-servers/c\ - --etcd-servers=https://10.8.138.10:2379,https://10.8.138.5:2379,https://10.8.138.6:2379" /etc/kubernetes/manifests/kube-apiserver.yaml'
|
查看etcd节点状态
1 2 3 4 5 6 7
| curl -L -O https://github.com/etcd-io/etcd/releases/download/v3.4.3/etcd-v3.4.3-linux-amd64.tar.gz tar xzf etcd-v3.4.3-linux-amd64.tar.gz mv etcd-v3.4.3-linux-amd64/etcd* /usr/local/bin/
ETCDCTL=3 etcdctl --write-out=table --cert /etc/kubernetes/pki/etcd/peer.crt --key /etc/kubernetes/pki/etcd/peer.key --cacert /etc/kubernetes/pki/etcd/ca.crt --endpoints https://10.8.138.10:2379,https://10.8.138.5:2379,https://10.8.138.6:2379 member list
|

查看集群状态
1
| ETCDCTL=3 etcdctl --cluster --write-out=table --cert /etc/kubernetes/pki/etcd/peer.crt --key /etc/kubernetes/pki/etcd/peer.key --cacert /etc/kubernetes/pki/etcd/ca.crt --endpoints https://10.8.138.10:2379,https://10.8.138.5:2379,https://10.8.138.6:2379 endpoint status
|

etcd节点健康状态
1
| ETCDCTL=3 etcdctl --cluster --write-out=table --cert /etc/kubernetes/pki/etcd/peer.crt --key /etc/kubernetes/pki/etcd/peer.key --cacert /etc/kubernetes/pki/etcd/ca.crt --endpoints https://10.8.138.10:2379,https://10.8.138.5:2379,https://10.8.138.6:2379 endpoint health
|

部署node节点
在所有node节点上执行下面的命令:
1 2
| kubeadm join 10.8.138.12:6443 --token z9ibq2.s5ttzyxvc49mep02 \ --discovery-token-ca-cert-hash sha256:71a025d1a18f9ec0f4c16ab771b2d01674ce9921316c87e0bdfd162d53f8524e
|
查看:
节点已经添加进来了,因为没有部署CNI所以都是NOTREADY。
部署calico
下载calico
1 2
| curl -L https://docs.projectcalico.org/v3.11/manifests/calico.yaml -o calico.yaml
|
部署calico
修改calico.yaml:
1 2 3 4 5 6 7
| - name: CALICO_IPV4POOL_CIDR value: "172.21.0.0/16"
- name: FELIX_KUBENODEPORTRANGES value: "30000:50000"
|
部署calico:
1
| kubectl apply -f calico.yaml
|
部署完成后,查看节点状态,应该都READY:
设置calico命令行工具
下载calico命令行工具:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| curl -L -o /usr/local/bin/calicoctl https://github.com/projectcalico/calicoctl/releases/download/v3.11.2/calicoctl-linux-amd64
mkdir -p /etc/calico cat > /etc/calico/calicoctl.cfg <<EOF apiVersion: projectcalico.org/v3 kind: CalicoAPIConfig metadata: spec: datastoreType: kubernetes kubeconfig: /etc/kubernetes/admin.conf # 使用 admin 配置 #k8sAPIEndpoint: https://10.8.138.12:6443 #k8sCertFile: /etc/kubernetes/pki/apiserver-kubelet-client.crt #k8sKeyFile: /etc/kubernetes/pki/apiserver-kubelet-client.key #k8sCAFile: /etc/kubernetes/pki/ca.crt EOF
|
查看calico节点
查看ippool
1 2 3 4
| calicoctl get ippool -o wide
NAME CIDR NAT IPIPMODE VXLANMODE DISABLED SELECTOR default-ipv4-ippool 172.21.0.0/16 true Always Never false all()
|
查看ip状态

集群校验
1 2
| kubectl config get-clusters kubectl cluster-info
|

nginx服务其配置
SCA-LUM700011
作为nginx服务器,将会代理ingress服务,所以先设置一下。
自签证书
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
| openssl version
nginx -V
cd /etc/nginx/ mkdir ssl cd ssl
openssl genrsa -out nginx.key 2048 Generating RSA private key, 2048 bit long modulus ..............................................+++ .....................................................................+++ e is 65537 (0x10001)
openssl req -new -key nginx.key -out nginx.csr
openssl req -subj "/C=CN/ST=Guangdong/L=Shenzhen/O=nginx/OU=dev/CN=test.example.com/emailAddress=test@123.com" -new -key nginx.key -out nginx.csr
openssl x509 -req -days 3650 -in nginx.csr -signkey nginx.key -out nginx.crt
$ ls nginx.crt nginx.csr nginx.key
|
修改nginx主配置文件
修改/etc/nginx/nginx.conf
文件为如下内容:
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
| user nginx; worker_processes 1;
error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid;
events { worker_connections 1024; }
http { include /etc/nginx/mime.types; default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf; }
|
这里使用include
导入其他的配置文件,所有服务的nginx配置都放在/etc/nginx/conf.d
下,如果目录不存在需要自己创建。
在``/etc/nginx/conf.d下先创建一个通用配置文件
common.ini`,这个是所有配置文件都要用的,所以抽离出来:
1 2 3 4 5 6 7 8
| location = /favicon.ico { log_not_found off; access_log off; }
location ~* /\.(svn|git)/ { return 404; }
|
创建一个测试配置
在/etc/nginx/conf.d
下新建一个配置文件https.conf
:
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
| server { listen 80; server_name https-server.example.com;
rewrite ^(.*) https://$host$1 permanent;
}
server { listen 443 ssl; server_name https-server.example.com;
ssl_certificate /etc/nginx/ssl/new/nginx.crt; ssl_certificate_key /etc/nginx/ssl/new/nginx.key;
access_log /var/log/nginx/https-server.example.com_access.log main; error_log /var/log/nginx/https-server.example.com_error.log;
location / { root /usr/share/nginx/html; index index.html index.htm; }
include conf.d/common.ini; }
|
在/usr/share/nginx/html
下创建测试页面:
1
| $ echo "this is https page" > /usr/share/nginx/html/index.html
|
绑定host
因为我是测试环境,且我要通过域名的方式访问服务,所以需要绑定host,这一步在自己的电脑上操作,过程不赘述。
重启nginx并访问
执行下面的命令检查配置并重新加载:
1 2
| nginx -t nginx -s reload
|
然后通过浏览器访问域名:https-server.example.com
,应该就可以看到设置的https页面了。
注意,有的浏览器对于自签证书是不信任的,需要手动下载证书然后在电脑中导入就可以了。