kubernetes使用ansible快速构建集群

2023-10-27

软硬件限制:

1)cpu和内存 master:至少1c2g,推荐2c4g;node:至少1c2g

2)linux系统 内核版本至少3.10,推荐CentOS7/RHEL7

3)docker 至少1.9版本,推荐1.12+ 4)etcd 至少2.0版本,推荐3.0+

kubernetes官方github地址 https://github.com/kubernetes/kubernetes/releases

高可用集群所需节点规划:

部署节点------x1 : 运行这份 ansible 脚本的节点 etcd节点------x3 : 注意etcd集群必须是1,3,5,7...奇数个节点

master节点----x2 : 根据实际集群规模可以增加节点数,需要额外规划一个master VIP(虚地址)

lb节点--------x2 : 负载均衡节点两个,安装 haproxy+keepalived

node节点------x3 : 真正应用负载的节点,根据需要提升机器配置和增加节点数

机器规划:
<table>
<tr>
<th>Ip</th>
<th>机名</th>
<th>角色</th>
<th>系统</th>
</tr>
<tr>
<th>192.168.2.10</th>
<th>master</th>
<th>deploy、master1、lb1、etcd</th>
<td rowspan="6">centos7.5 x86_64</td>
</tr>
<tr>
<th>192.168.2.11</th>
<th>node1</th>
<th>etcd、node</th>
</tr>
<tr>
<th>192.168.2.12</th>
<th>node2</th>
<th>etcd、node</th>
</tr>
<tr>
<th>192.168.2.13</th>
<th>node3</th>
<th>node</th>
</tr>
<tr>
<th>192.168.2.14</th>
<th>master2</th>
<th>master2、lb2</th>
</tr>
<tr>
<th>192.168.2.16</th>
<th></th>
<th>vip</th>
</tr>
</table>

准备工作

安装epel源、python

六台机器,全部执行:

yum install epel-release

yum update

yum install python

deploy节点安装和准备ansible

yum install -y python-pip  git

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

deploy节点配置免密码登录

奉上我使用多年的自动布置key的脚本

#!/bin/bash
keypath=/root/.ssh
[ -d ${keypath} ] || mkdir -p ${keypath}
rpm -q expect &> /dev/null || yum install expect -y
ssh-keygen -t rsa -f /root/.ssh/id_rsa  -P ""
password=centos
for host in `seq 10 14`;do
expect <<EOF
set timeout 5
spawn ssh-copy-id 192.168.2.$host
expect {
"yes/no" { send "yes\n";exp_continue }
"password" { send "$password\n"  }
}
expect eof
EOF
done

执行脚本,deploy自动copy key到目标主机

[root@master ~]# sh sshkey.sh 

deploy上编排k8s

git clone https://github.com/gjmzj/kubeasz.git

mkdir -p /etc/ansible

mv kubeasz/* /etc/ansible/

从百度云网盘下载二进制文件 https://pan.baidu.com/s/1c4RFaA#list/path=%2F

可以根据自己所需版本,下载对应的tar包,这里我下载1.12

经过一番折腾, 终把k8s.1-12-1.tar.gz的tar包放到了depoly上

tar zxvf k8s.1-12-1.tar.gz 
mv bin/* /etc/ansible/bin/

Example:

[root@master ~]# rz
rz waiting to receive.
Starting zmodem transfer.  Press Ctrl+C to cancel.
Transferring k8s.1-12-1.tar.gz...
  100%  234969 KB    58742 KB/sec    00:00:04       0 Errors  

[root@master ~]# ls
anaconda-ks.cfg  ifcfg-ens192.bak  k8s.1-12-1.tar.gz  kubeasz
[root@master ~]# tar zxf k8s.1-12-1.tar.gz 
[root@master ~]# ls
anaconda-ks.cfg  bin  ifcfg-ens192.bak  k8s.1-12-1.tar.gz  kubeasz
[root@master ~]# mv bin /etc/ansible/

mv:是否覆盖"/etc/ansible/bin/readme.md"? y

配置集群参数

cd /etc/ansible/

cp example/hosts.m-masters.example hosts  //内容根据实际情况修改
[deploy]
192.168.2.10 NTP_ENABLED=no

# 'etcd' cluster must have odd member(s) (1,3,5,...)
# variable 'NODE_NAME' is the distinct name of a member in 'etcd' cluster
[etcd]
192.168.2.10 NODE_NAME=etcd1
192.168.2.11 NODE_NAME=etcd2
192.168.2.12 NODE_NAME=etcd3

[kube-master]
192.168.2.10
# 'loadbalance' node, with 'haproxy+keepalived' installed
[lb]
192.168.2.10 LB_IF="eth0" LB_ROLE=backup  # replace 'etho' with node's network interface
192.168.2.14 LB_IF="eth0" LB_ROLE=master

[kube-node]
192.168.2.11
192.168.2.12
192.168.2.13

[vip]
192.168.2.15

修改完hosts,测试

ansible all -m ping

[root@master ansible]# ansible all -m ping
192.168.2.11 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.2.14 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.2.12 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.2.10 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.2.13 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.2.15 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

分步骤安装:

1)创建证书和安装准备

ansible-playbook 01.prepare.yml

2)安装etcd集群

ansible-playbook 02.etcd.yml

检查etcd节点健康状况:
执行bash

 for ip in 10 11 12 ; do ETCDCTL_API=3 etcdctl --endpoints=https://192.168.2.$ip:2379 --cacert=/etc/kubernetes/ssl/ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem endpoint healt; done

执行后:

https://192.168.2.10:2379 is healthy: successfully committed proposal: took = 857.393µs
https://192.168.2.11:2379 is healthy: successfully committed proposal: took = 1.0619ms
https://192.168.2.12:2379 is healthy: successfully committed proposal: took = 1.19245ms

或者 添加/etc/ansible/bin环境变量:

[root@master ansible]# vim /etc/profile.d/k8s.sh
export PATH=$PATH:/etc/ansible/bin

[root@master ansible]# for ip in 10 11 12 ; do ETCDCTL_API=3 etcdctl --endpoints=https://192.168.2.$ip:2379 --cacert=/etc/kubernetes/ssl/ca.pem --cert=/etc/etcd/ssl/etcd.pem --key=/etc/etcd/ssl/etcd-key.pem endpoint healt; done

https://192.168.2.10:2379 is healthy: successfully committed proposal: took = 861.891µs
https://192.168.2.11:2379 is healthy: successfully committed proposal: took = 1.061687ms
https://192.168.2.12:2379 is healthy: successfully committed proposal: took = 909.274µs

3)安装docker

ansible-playbook 03.docker.yml

4)安装master节点

ansible-playbook 04.kube-master.yml
kubectl get componentstatus//查看集群状态

NAME                 STATUS    MESSAGE          ERROR
controller-manager   Healthy   ok                  
scheduler            Healthy   ok                  
etcd-0               Healthy   {"health":"true"}   
etcd-1               Healthy   {"health":"true"}   
etcd-2               Healthy   {"health":"true"}   

5)安装node节点

ansible-playbook 05.kube-node.yml

查看node节点

kubectl get nodes
[root@master ansible]# kubectl get nodes
NAME           STATUS                     ROLES    AGE    VERSION
192.168.2.10   Ready,SchedulingDisabled   master   112s   v1.12.1
192.168.2.11   Ready                      node     17s    v1.12.1
192.168.2.12   Ready                      node     17s    v1.12.1
192.168.2.13   Ready                      node     17s    v1.12.1
192.168.2.14   Ready,SchedulingDisabled   master   112s   v1.12.1

6)部署集群网络

ansible-playbook 06.network.yml
kubectl get pod -n kube-system  //查看kube-systemnamespace上的pod,从中可以看到flannel相关的pod

[root@master ansible]# kubectl get pod -n kube-system
NAME                    READY   STATUS    RESTARTS   AGE
kube-flannel-ds-5d574   1/1     Running   0          47s
kube-flannel-ds-6kpnm   1/1     Running   0          47s
kube-flannel-ds-f2nfs   1/1     Running   0          47s
kube-flannel-ds-gmbmv   1/1     Running   0          47s
kube-flannel-ds-w5st7   1/1     Running   0          47s

7)安装集群插件(dns, dashboard)

ansible-playbook 07.cluster-addon.yml

查看kube-system namespace下的服务

kubectl get svc -n  kube-system
[root@master ~]# kubectl get svc -n  kube-system
NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
kube-dns               ClusterIP   10.68.0.2       <none>        53/UDP,53/TCP   10h
kubernetes-dashboard   NodePort    10.68.119.108   <none>        443:35065/TCP   10h
metrics-server         ClusterIP   10.68.235.9     <none>        443/TCP         10h    

查看admin登录dashboard的 token

到此为止,分步部署已经基本配置完毕了,下面就可以查找登录token登录dashboard了:

[root@master ~]# kubectl get secret -n kube-system|grep admin
admin-user-token-4zdgw             kubernetes.io/service-account-token   3      9h
[root@master ~]# kubectl describe secret admin-user-token-4zdgw -n kube-system
Name:         admin-user-token-4zdgw
Namespace:    kube-system
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: admin-user
              kubernetes.io/service-account.uid: 72378c78-ee7d-11e8-a2a7-000c2931fb97

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1346 bytes
namespace:  11 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLTR6ZGd3Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI3MjM3OGM3OC1lZTdkLTExZTgtYTJhNy0wMDBjMjkzMWZiOTciLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06YWRtaW4tdXNlciJ9.J0MjCSAP00RDvQgG1xBPvAYVo1oycXfoBh0dqdCzX1ByILyCHUqqxixuQdfE-pZqP15u6UV8OF3lGI_mHs5DBvNK0pCfaRICSo4SXSihJHKl_j9Bbozq9PjQ5d7CqHOFoXk04q0mWpJ5o0rJ6JX6Psx93Ch0uaXPPMLtzL0kolIF0j1tCFnsob8moczH06hfzo3sg8h0YCXyO6Z10VT7GMuLlwiG8XgWcplm-vcPoY_AWHnLV3RwAJH0u1q0IrMprvgTCuHighTaSjPeUe2VsXMhDpocJMoHQOoHirQKmiIAnanbIm4N1TO_5R1cqh-_gH7-MH8xefgWXoSrO-fo2w

登录了账号密码后,用上面token在界面上登录即可
kubernetes使用ansible快速构建集群
也可以查询证.

[root@master ~]# kubectl get secret -n kube-system
NAME                               TYPE                                  DATA   AGE
admin-user-token-4zdgw             kubernetes.io/service-account-token   3      10h
coredns-token-98zvm                kubernetes.io/service-account-token   3      10h
default-token-zk5rj                kubernetes.io/service-account-token   3      10h
flannel-token-4gmtz                kubernetes.io/service-account-token   3      10h
kubernetes-dashboard-certs         Opaque                                0      10h
kubernetes-dashboard-key-holder    Opaque                                2      10h
kubernetes-dashboard-token-lcsd6   kubernetes.io/service-account-token   3      10h
metrics-server-token-j4s2c         kubernetes.io/service-account-token   3      10h
[root@master ~]# kubectl get secret/admin-user-token-4zdgw -n kube-system -o yaml
apiVersion: v1
data:
  ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUR0akNDQXA2Z0F3SUJBZ0lVVFB3YVdFR0gyT2kwaHlVeGlJWnhFSUF3UFpVd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1lURUxNQWtHQTFVRUJoTUNRMDR4RVRBUEJnTlZCQWdUQ0VoaGJtZGFhRzkxTVFzd0NRWURWUVFIRXdKWQpVekVNTUFvR0ExVUVDaE1EYXpoek1ROHdEUVlEVlFRTEV3WlRlWE4wWlcweEV6QVJCZ05WQkFNVENtdDFZbVZ5CmJtVjBaWE13SGhjTk1UZ3hNVEl5TVRZeE1EQXdXaGNOTXpNeE1URTRNVFl4TURBd1dqQmhNUXN3Q1FZRFZRUUcKRXdKRFRqRVJNQThHQTFVRUNCTUlTR0Z1WjFwb2IzVXhDekFKQmdOVkJBY1RBbGhUTVF3d0NnWURWUVFLRXdOcgpPSE14RHpBTkJnTlZCQXNUQmxONWMzUmxiVEVUTUJFR0ExVUVBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKCktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU5zV1NweVVRcGYvWDFCaHNtUS9NUDVHVE0zcUFjWngKV3lKUjB0VEtyUDVWNStnSjNZWldjK01HSzlrY3h6OG1RUUczdldvNi9ENHIyZ3RuREVWaWxRb1dlTm0rR3hLSwpJNjkzczNlS2ovM1dIdGloOVA4TWp0RktMWnRvSzRKS09kUURYeGFHLzJNdzJEMmZnbzNJT2VDdlZzR0F3Qlc4ClYxMDh3dUVNdTIzMnhybFdSSFFWaTNyc0dmN3pJbkZzSFNOWFFDbXRMMHhubERlYnZjK2c2TWRtcWZraVZSdzIKNTFzZGxnbmV1aEFqVFJaRkYvT0lFWE4yUjIyYTJqZVZDbWNySEcvK2orU0tzTlpmeVVCb216NGRUcmRsV0JEUQpob3ZzSGkrTEtJVGNxZHBQV3MrZmxIQjlaL1FRUnM5MTZEREpxMHRWNFV6MEY0YjRsemJXaGdrQ0F3RUFBYU5tCk1HUXdEZ1lEVlIwUEFRSC9CQVFEQWdFR01CSUdBMVVkRXdFQi93UUlNQVlCQWY4Q0FRSXdIUVlEVlIwT0JCWUUKRklaN3NZczRjV0xtYnlwVUEwWUhGanc3Mk5jV01COEdBMVVkSXdRWU1CYUFGSVo3c1lzNGNXTG1ieXBVQTBZSApGanc3Mk5jV01BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQ2Eyell1NmVqMlRURWcyN1VOeGh4U0ZMaFJLTHhSClg5WnoyTmtuVjFQMXhMcU8xSHRUSmFYajgvL0wxUmdkQlRpR3JEOXNENGxCdFRRMmF2djJFQzZKeXJyS0xVelUKSWNiUXNpU0h4NkQ3S1FFWjFxQnZkNWRKVDluai9mMG94SjlxNDVmZTBJbWNiUndKWnA2WDJKbWtQSWZyYjYreQo2YUFTbzhaakliTktQN1Z1WndIQ1RPQUwzeUhVR2lJTEJtT1hKNldGRDlpTWVFMytPZE95ZHIwYzNvUmRXVW1aCkI1andlN2x2MEtVc2Y1SnBTS0JCbzZ3bkViNXhMdDRSYjBMa2RxMXZLTGFOMXUvbXFFc1ltbUk3MmRuaUdLSTkKakdDdkRqNVREaW55T1RQU005Vi81RE5OTFlLQkExaDRDTmVBRjE1RWlCay9EU055SzIrUTF3TVgKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
  namespace: a3ViZS1zeXN0ZW0=
  token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNklpSjkuZXlKcGMzTWlPaUpyZFdKbGNtNWxkR1Z6TDNObGNuWnBZMlZoWTJOdmRXNTBJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5dVlXMWxjM0JoWTJVaU9pSnJkV0psTFhONWMzUmxiU0lzSW10MVltVnlibVYwWlhNdWFXOHZjMlZ5ZG1salpXRmpZMjkxYm5RdmMyVmpjbVYwTG01aGJXVWlPaUpoWkcxcGJpMTFjMlZ5TFhSdmEyVnVMVFI2WkdkM0lpd2lhM1ZpWlhKdVpYUmxjeTVwYnk5elpYSjJhV05sWVdOamIzVnVkQzl6WlhKMmFXTmxMV0ZqWTI5MWJuUXVibUZ0WlNJNkltRmtiV2x1TFhWelpYSWlMQ0pyZFdKbGNtNWxkR1Z6TG1sdkwzTmxjblpwWTJWaFkyTnZkVzUwTDNObGNuWnBZMlV0WVdOamIzVnVkQzUxYVdRaU9pSTNNak0zT0dNM09DMWxaVGRrTFRFeFpUZ3RZVEpoTnkwd01EQmpNamt6TVdaaU9UY2lMQ0p6ZFdJaU9pSnplWE4wWlcwNmMyVnlkbWxqWldGalkyOTFiblE2YTNWaVpTMXplWE4wWlcwNllXUnRhVzR0ZFhObGNpSjkuSjBNakNTQVAwMFJEdlFnRzF4QlB2QVlWbzFveWNYZm9CaDBkcWRDelgxQnlJTHlDSFVxcXhpeHVRZGZFLXBacVAxNXU2VVY4T0YzbEdJX21IczVEQnZOSzBwQ2ZhUklDU280U1hTaWhKSEtsX2o5QmJvenE5UGpRNWQ3Q3FIT0ZvWGswNHEwbVdwSjVvMHJKNkpYNlBzeDkzQ2gwdWFYUFBNTHR6TDBrb2xJRjBqMXRDRm5zb2I4bW9jekgwNmhmem8zc2c4aDBZQ1h5TzZaMTBWVDdHTXVMbHdpRzhYZ1djcGxtLXZjUG9ZX0FXSG5MVjNSd0FKSDB1MXEwSXJNcHJ2Z1RDdUhpZ2hUYVNqUGVVZTJWc1hNaERwb2NKTW9IUU9vSGlyUUttaUlBbmFuYkltNE4xVE9fNVIxY3FoLV9nSDctTUg4eGVmZ1dYb1NyTy1mbzJ3
kind: Secret
metadata:
  annotations:
    kubernetes.io/service-account.name: admin-user
    kubernetes.io/service-account.uid: 72378c78-ee7d-11e8-a2a7-000c2931fb97
  creationTimestamp: 2018-11-22T17:38:38Z
  name: admin-user-token-4zdgw
  namespace: kube-system
  resourceVersion: "977"
  selfLink: /api/v1/namespaces/kube-system/secrets/admin-user-token-4zdgw
  uid: 7239bb01-ee7d-11e8-8c5c-000c29fd1c0f
type: kubernetes.io/service-account-token

查看ServiceAccount

ServiceAccount 是一种账号,但是不是为集群用户(管理员、运维人员等)使用的,而是给运行在集群中的 Pod 里面的进程使用的。

[root@master ~]# kubectl get serviceaccount --all-namespaces
NAMESPACE     NAME                   SECRETS   AGE
default       default                1         10h
kube-public   default                1         10h
kube-system   admin-user             1         10h
kube-system   coredns                1         10h
kube-system   default                1         10h
kube-system   flannel                1         10h
kube-system   kubernetes-dashboard   1         10h
kube-system   metrics-server         1         10h
[root@master ~]# kubectl describe serviceaccount/default -n kube-system
Name:                default
Namespace:           kube-system
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   default-token-zk5rj
Tokens:              default-token-zk5rj
Events:              <none>
[root@master ~]# kubectl get secret/default-token-zk5rj -n kube-system
NAME                  TYPE                                  DATA   AGE
default-token-zk5rj   kubernetes.io/service-account-token   3      10h
[root@master ~]# kubectl get secret/default-token-zk5rj -n kube-system -o yaml
apiVersion: v1
data:
  ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUR0akNDQXA2Z0F3SUJBZ0lVVFB3YVdFR0gyT2kwaHlVeGlJWnhFSUF3UFpVd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1lURUxNQWtHQTFVRUJoTUNRMDR4RVRBUEJnTlZCQWdUQ0VoaGJtZGFhRzkxTVFzd0NRWURWUVFIRXdKWQpVekVNTUFvR0ExVUVDaE1EYXpoek1ROHdEUVlEVlFRTEV3WlRlWE4wWlcweEV6QVJCZ05WQkFNVENtdDFZbVZ5CmJtVjBaWE13SGhjTk1UZ3hNVEl5TVRZeE1EQXdXaGNOTXpNeE1URTRNVFl4TURBd1dqQmhNUXN3Q1FZRFZRUUcKRXdKRFRqRVJNQThHQTFVRUNCTUlTR0Z1WjFwb2IzVXhDekFKQmdOVkJBY1RBbGhUTVF3d0NnWURWUVFLRXdOcgpPSE14RHpBTkJnTlZCQXNUQmxONWMzUmxiVEVUTUJFR0ExVUVBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKCktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU5zV1NweVVRcGYvWDFCaHNtUS9NUDVHVE0zcUFjWngKV3lKUjB0VEtyUDVWNStnSjNZWldjK01HSzlrY3h6OG1RUUczdldvNi9ENHIyZ3RuREVWaWxRb1dlTm0rR3hLSwpJNjkzczNlS2ovM1dIdGloOVA4TWp0RktMWnRvSzRKS09kUURYeGFHLzJNdzJEMmZnbzNJT2VDdlZzR0F3Qlc4ClYxMDh3dUVNdTIzMnhybFdSSFFWaTNyc0dmN3pJbkZzSFNOWFFDbXRMMHhubERlYnZjK2c2TWRtcWZraVZSdzIKNTFzZGxnbmV1aEFqVFJaRkYvT0lFWE4yUjIyYTJqZVZDbWNySEcvK2orU0tzTlpmeVVCb216NGRUcmRsV0JEUQpob3ZzSGkrTEtJVGNxZHBQV3MrZmxIQjlaL1FRUnM5MTZEREpxMHRWNFV6MEY0YjRsemJXaGdrQ0F3RUFBYU5tCk1HUXdEZ1lEVlIwUEFRSC9CQVFEQWdFR01CSUdBMVVkRXdFQi93UUlNQVlCQWY4Q0FRSXdIUVlEVlIwT0JCWUUKRklaN3NZczRjV0xtYnlwVUEwWUhGanc3Mk5jV01COEdBMVVkSXdRWU1CYUFGSVo3c1lzNGNXTG1ieXBVQTBZSApGanc3Mk5jV01BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQ2Eyell1NmVqMlRURWcyN1VOeGh4U0ZMaFJLTHhSClg5WnoyTmtuVjFQMXhMcU8xSHRUSmFYajgvL0wxUmdkQlRpR3JEOXNENGxCdFRRMmF2djJFQzZKeXJyS0xVelUKSWNiUXNpU0h4NkQ3S1FFWjFxQnZkNWRKVDluai9mMG94SjlxNDVmZTBJbWNiUndKWnA2WDJKbWtQSWZyYjYreQo2YUFTbzhaakliTktQN1Z1WndIQ1RPQUwzeUhVR2lJTEJtT1hKNldGRDlpTWVFMytPZE95ZHIwYzNvUmRXVW1aCkI1andlN2x2MEtVc2Y1SnBTS0JCbzZ3bkViNXhMdDRSYjBMa2RxMXZLTGFOMXUvbXFFc1ltbUk3MmRuaUdLSTkKakdDdkRqNVREaW55T1RQU005Vi81RE5OTFlLQkExaDRDTmVBRjE1RWlCay9EU055SzIrUTF3TVgKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
  namespace: a3ViZS1zeXN0ZW0=
  token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNklpSjkuZXlKcGMzTWlPaUpyZFdKbGNtNWxkR1Z6TDNObGNuWnBZMlZoWTJOdmRXNTBJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5dVlXMWxjM0JoWTJVaU9pSnJkV0psTFhONWMzUmxiU0lzSW10MVltVnlibVYwWlhNdWFXOHZjMlZ5ZG1salpXRmpZMjkxYm5RdmMyVmpjbVYwTG01aGJXVWlPaUprWldaaGRXeDBMWFJ2YTJWdUxYcHJOWEpxSWl3aWEzVmlaWEp1WlhSbGN5NXBieTl6WlhKMmFXTmxZV05qYjNWdWRDOXpaWEoyYVdObExXRmpZMjkxYm5RdWJtRnRaU0k2SW1SbFptRjFiSFFpTENKcmRXSmxjbTVsZEdWekxtbHZMM05sY25acFkyVmhZMk52ZFc1MEwzTmxjblpwWTJVdFlXTmpiM1Z1ZEM1MWFXUWlPaUpoTkRKaE9EUmlaQzFsWlRkakxURXhaVGd0T0dNMVl5MHdNREJqTWpsbVpERmpNR1lpTENKemRXSWlPaUp6ZVhOMFpXMDZjMlZ5ZG1salpXRmpZMjkxYm5RNmEzVmlaUzF6ZVhOMFpXMDZaR1ZtWVhWc2RDSjkuSTBqQnNkVk1udUw1Q2J2VEtTTGtvcFFyd1h4NTlPNWt0YnVJUHVaemVNTjJjdmNvTE9icS1Xa0NRWWVaaDEwdUFsWVBUbnAtTkxLTFhLMUlrQVpab3dzcllKVmJsQmdQVmVOUDhtOWJ4dk5HXzlMVjcyNGNOaU1aT2pfQ0ExREJEVF91eHlXWlF0eUEwZ0RpeTBRem1zMnZrVEpaZFNHQUZ6V2NVdjA1QWlsdUxaUUhLZmMyOWpuVGJERUhxT2U1UXU2cjRXd05qLTA0SE5qUzFpMHpzUGFkbmR0bzVSaUgtcThaSTVVT3hsNGYyUXlTMlJrWmdtV0tEM2tRaVBWUHpLZDRqRmJsLWhHN3VhQjdBSUVwcHBaUzVYby1USEFhRjJTSi1SUUJfenhDTG42QUZhU0EwcVhrYWhGYmpET0s0OTlZRTVlblJrNkpIRmZVWnR0YmlB
kind: Secret
metadata:
  annotations:
    kubernetes.io/service-account.name: default
    kubernetes.io/service-account.uid: a42a84bd-ee7c-11e8-8c5c-000c29fd1c0f
  creationTimestamp: 2018-11-22T17:32:53Z
  name: default-token-zk5rj
  namespace: kube-system
  resourceVersion: "175"
  selfLink: /api/v1/namespaces/kube-system/secrets/default-token-zk5rj
  uid: a42daa94-ee7c-11e8-8c5c-000c29fd1c0f
type: kubernetes.io/service-account-token

一键全自动安装

合并所有步骤的安装,和分步安装一样的效果:

ansible-playbook 90.setup.yml

查看集群信息:

kubectl cluster-info

[root@master ~]# kubectl cluster-info 
Kubernetes master is running at https://192.168.2.16:8443
CoreDNS is running at https://192.168.2.16:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
kubernetes-dashboard is running at https://192.168.2.16:8443/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy

查看node/pod使用资源情况:

kubectl top node

kubectl top pod --all-namespaces

测试DNS

a) 创建nginx service

kubectl run nginx --image=nginx --expose --port=80

b)创建alpine 测试pod

kubectl run b1 -it --rm --image=alpine /bin/sh //进入到alpine内部

nslookup nginx.default.svc.cluster.local //结果如下

 Address 1: 10.68.167.102 nginx.default.svc.cluster.local

增加node节点

1)deploy节点免密码登录node

ssh-copy-id 新node ip

2)修改/etc/ansible/hosts

[new-node]
192.168.2.15

3)执行安装脚本

ansible-playbook /etc/ansible/20.addnode.yml

4)验证

kubectl get node

kubectl get pod -n kube-system -o wide

5)后续工作

修改/etc/ansible/hosts,将new-node里面的所有ip全部移动到kube-node组里去

增加master节点(略)

https://github.com/gjmzj/kubeasz/blob/master/docs/op/AddMaster.md 升级集群

1)备份etcd

ETCDCTL_API=3 etcdctl snapshot save backup.db

查看备份文件信息

ETCDCTL_API=3 etcdctl --write-out=table snapshot status backup.db

2

)到本项目的根目录kubeasz

cd  /dir/to/kubeasz

拉取最新的代码

git pull origin master

3)下载升级目标版本的kubernetes二进制包(百度网盘https://pan.baidu.com/s/1c4RFaA#list/path=%2F)解压,并替换/etc/ansible/bin/下的二进制文件

4)docker升级(略),除非特别需要,否则不建议频繁升级docker

5)如果接受业务中断,执行:

ansible-playbook -t upgrade_k8s,restart_dockerd 22.upgrade.yml

6)不能接受短暂中断,需要这样做:

a)

ansible-playbook -t upgrade_k8s 22.upgrade.yml

b)到所有node上逐一:

kubectl cordon和kubectl drain  //迁移业务pod

systemctl restart docker

kubectl uncordon  //恢复pod

备份和恢复

1)备份恢复原理:

备份,从运行的etcd集群中备份数据到磁盘文件恢复,把etcd的备份文件恢复到etcd集群中,然后据此重建整个集群

2)如果使用kubeasz项目创建的集群,除了备份etcd数据外,还需要备份CA证书文件,以及ansible的hosts文件

3)手动操作步骤:

mkdir -p ~/backup/k8s  //创建备份目录

ETCDCTL_API=3 etcdctl snapshot save ~/backup/k8s/snapshot.db  //备份etcd数据 

cp /etc/kubernetes/ssl/ca* ~/backup/k8s/  //备份ca证书

deploy节点执行

ansible-playbook /etc/ansible/99.clean.yml //模拟集群崩

溃恢复步骤如下(在deploy节点):

a)恢复ca证书

mkdir -p /etc/kubernetes/ssl /backup/k8s
cp ~/backup/k8s/* /backup/k8s/
cp /backup/k8s/ca* /etc/kubernetes/ssl/

b)重建集群
只需执行前5步,其他的在etcd保存着。

cd /etc/ansibl
ansible-playbook 01.prepare.yml

ansible-playbook 02.etcd.yml

ansible-playbook 03.docker.yml

ansible-playbook 04.kube-master.yml

ansible-playbook 05.kube-node.yml

c)恢复etcd数据

停止服务

ansible etcd -m service -a 'name=etcd state=stopped'

清空文件

ansible etcd -m file -a 'name=/var/lib/etcd/member/ state=absent'

登录所有的etcd节点,参照本etcd节点/etc/systemd/system/etcd.service的服务文件,替换如下{{}}中变量后执行

cd /backup/k8s/ 

ETCDCTL_API=3 etcdctl snapshot restore snapshot.db \  
-name etcd1 \ 
-initialcluster etcd1=https://192.168.2.10:2380,etcd2=https://192.168.2.11:2380,etcd3=https://192.168.2.12:2380 \
-initial-cluster-token etcd-cluster-0 \
--initial-advertise-peer-urls https://192.168.2.10:2380

执行上面的步骤后,会生成{{ NODE_NAME }}.etcd目录

cp -r etcd1.etcd/member /var/lib/etcd/

systemctl restart  etcd

d)在deploy节点重建网络

ansible-playbook /etc/ansible/tools/change_k8s_network.yml

4)不想手动恢复,可以用ansible自动恢复

需要一键备份

ansible-playbook /etc/ansible/23.backup.yml

检查/etc/ansible/roles/cluster-backup/files目录下是否有文件

tree /etc/ansible/roles/cluster-backup/files/ //如下

├── ca              #集群CA相关备份
|   ├── ca-config.json
|   ├── ca.csr
|   ├── ca-csr.json
|   ├── ca-key.pem
|   └── ca.pem
├── hosts           # ansible hosts备份
|   ├── hosts       #最近的备份
|   └── hosts-201807231642
|── readme.md
└── snapshot          # etcd数据备份
     ├── snapshot-201807231642.db
     └── snapshot.db    #最近的备份

模拟故障:

ansible-playbook /etc/ansible/99.clean.yml

修改文件/etc/ansible/roles/cluster-restore/defaults/main.yml,指定要恢复的etcd快照备份,如果不修改就是 新的一次

恢复操作:

ansible-playbook /etc/ansible/24.restore.yml

ansible-playbook /etc/ansible/tools/change_k8s_network.yml

可选

对集群所有节点进行操作系统层面的安全加固

ansible-playbook roles/os-harden/os-harden.yml

详情请参考os-harden项目

考文档:

本文档参考 https://github.com/gjmzj/kubeasz 扩展:使用kubeadm部署集群 https://blog.frognew.com/2018/08/kubeadm-install-kubernetes-1.11.html

转载于:https://blog.51cto.com/m51cto/2344825

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

kubernetes使用ansible快速构建集群 的相关文章

  • python 相当于 R 中的 get() (= 使用字符串检索符号的值)

    在 R 中 get s 函数检索名称存储在字符变量 向量 中的符号的值s e g X lt 10 r lt XVI s lt substr r 1 1 X get s 10 取罗马数字的第一个符号r并将其转换为其等效整数 尽管花了一些时间翻
  • 如何从网页中嵌入的 Tableau 图表中抓取工具提示值

    我试图弄清楚是否有一种方法以及如何使用 python 从网页中的 Tableau 嵌入图形中抓取工具提示值 以下是当用户将鼠标悬停在条形上时带有工具提示的图表示例 我从要从中抓取的原始网页中获取了此网址 https covid19 colo
  • Python pickle:腌制对象不等于源对象

    我认为这是预期的行为 但想检查一下 也许找出原因 因为我所做的研究结果是空白 我有一个函数可以提取数据 创建自定义类的新实例 然后将其附加到列表中 该类仅包含变量 然后 我使用协议 2 作为二进制文件将该列表腌制到文件中 稍后我重新运行脚本
  • 如何格式化 Highcharts 的 (x,y) 对数据的日期时间

    我的序列化方法会产生如下所示的日期时间字符串 2014 07 09T12 30 41Z 为什么下面的代码不起作用 function container highcharts xAxis type datetime series data x
  • OpenCV 无法从 MacBook Pro iSight 捕获

    几天后 我无法再从 opencv 应用程序内部打开我的 iSight 相机 cap cv2 VideoCapture 0 返回 并且cap isOpened 回报true 然而 cap grab 刚刚返回false 有任何想法吗 示例代码
  • 如何使用 OpencV 从 Firebase 读取图像?

    有没有使用 OpenCV 从 Firebase 读取图像的想法 或者我必须先下载图片 然后从本地文件夹执行 cv imread 功能 有什么办法我可以使用cv imread link of picture from firebase 您可以
  • AWS EMR Spark Python 日志记录

    我正在 AWS EMR 上运行一个非常简单的 Spark 作业 但似乎无法从我的脚本中获取任何日志输出 我尝试过打印到 stderr from pyspark import SparkContext import sys if name m
  • 如何在ipywidget按钮中显示全文?

    我正在创建一个ipywidget带有一些文本的按钮 但按钮中未显示全文 我使用的代码如下 import ipywidgets as widgets from IPython display import display button wid
  • 在 .gitconfig 中隐藏 GitHub 令牌

    我想将所有点文件存储在 GitHub 上 包括 gitconfig 这需要我将 GitHub 令牌隐藏在 gitconfig 中 为此 我有一个 gitconfig hidden token 文件 这是我打算编辑并放在隐藏令牌的 git 下
  • Python 的“zip”内置函数的 Ruby 等价物是什么?

    Ruby 是否有与 Python 内置函数等效的东西zip功能 如果不是 做同样事情的简洁方法是什么 一些背景信息 当我试图找到一种干净的方法来进行涉及两个数组的检查时 出现了这个问题 如果我有zip 我可以写这样的东西 zip a b a
  • jQuery:处理 getJSON() 中的错误?

    使用 jQuery 时如何处理 500 错误getJSON http api jquery com jQuery getJSON 有几个关于错误处理的问题getJSON and https stackoverflow com questio
  • 为什么“git描述-dirty”在描述干净结帐时添加“-dirty”后缀?

    我刚刚发现 dirty选项git describe看起来它应该做一些非常有用的事情 即在输出中附加一个后缀git describe当工作树脏时 但是在我的一些存储库上似乎并非如此 git status On branch 8 30 noth
  • Pandas:merge_asof() 对多行求和/不重复

    我正在处理两个数据集 每个数据集具有不同的关联日期 我想合并它们 但因为日期不完全匹配 我相信merge asof 是最好的方法 然而 有两件事发生merge asof 不理想的 数字重复 数字丢失 以下代码是一个示例 df a pd Da
  • Fabric env.roledefs 未按预期运行

    On the 面料网站 http docs fabfile org en 1 10 usage execution html 给出这个例子 from fabric api import env env roledefs web hosts
  • 将图像分割成多个网格

    我使用下面的代码将图像分割成网格的 20 个相等的部分 import cv2 im cv2 imread apple jpg im cv2 resize im 1000 500 imgwidth im shape 0 imgheight i
  • 有没有办法检测正在运行的代码是否正在上下文管理器内执行?

    正如标题所述 有没有办法做到这样的事情 def call back if called inside context print running in context else print called outside context 这将
  • 有人用过 Dabo 做过中型项目吗? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我们正处于一个新的 ERP 风格的客户端 服务器应用程序的开始阶段 该应用程序是作为 Python 富客户端开发的 我们目前正在评估 Dabo
  • Python:如何将列表列表的元素转换为无向图?

    我有一个程序 可以检索 PubMed 出版物列表 并希望构建一个共同作者图 这意味着对于每篇文章 我想将每个作者 如果尚未存在 添加为顶点 并添加无向边 或增加每个合著者之间的权重 我设法编写了第一个程序 该程序检索每个出版物的作者列表 并
  • 发送用户注册密码,django-allauth

    我在 django 应用程序上使用 django alluth 进行身份验证 注册 我需要创建一个自定义注册表单 其中只有一个字段 电子邮件 密码将在服务器上生成 这是我创建的表格 from django import forms from
  • 如何将输入读取为数字?

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 Why are x and y下面的代码中使用字符串而不是整数 注意 在Python 2

随机推荐

  • jsp里怎么获取input里的值 在function里用

    第一种 通过getElementById找到input节点 然后获取value属性 1 定义一个input节点
  • 使用 CloudFlare 免费 CDN 加速 WordPress

    具体使用参考文章 CloudFlare 免费 CDN 加速使用方法 你似乎来到了没有知识存在的荒原 知乎 CloudFlare 免费 CDN 优化指南 CloudFlare免费CDN优化指南 知乎 CloudFlare 加速 WordPre
  • Wireshark 抓包工具使用记录

    1 搜索 Wireshark 安装 注意要中途要安装 pcap 否则会提示 找不到网络 安装过程全部默认选项 2 抓取移动端软件接口包 在安装了Winpcap 的电脑上 分一个wifi 360wifi等等 用手机连接这个wifi 然后启动
  • Docker部署单点Elasticsearch与Kibana

    一 创建网络 因为需要部署kibana容器 因此需要让es和kibana容器互联 这里创建一个网络 docker network create es net 创建一个网络名称为 es net 二 拉取并加载镜像 方式一 docker pul
  • 台词生成器 (html5 版)

    最近经常看到别人 PS 来恶搞 泰囧 电影中的台词 觉得挺好玩的 先上效果图 就想用 html5 自己也做一个来玩玩 查了下 API 发现还是挺简单的 context fillText text x y width 参数 text 要生成的
  • Eclipse快捷键大全

    快捷键 Eclipse中有如下一些和编辑相关的快捷键 1 ALT 此快捷键为用户编辑的好帮手 能为用户提供内容的辅助 不要为记不全方法和属性名称犯愁 当记不全类 方法和属性的名字时 多体验一下 ALT 快捷键带来的好处吧 2 Ctrl O
  • Spring Boot之 Controller 接收参数和返回数据总结(包括上传、下载文件)

    转载自 https blog csdn net jy02268879 article details 82830789 一 接收参数 postman发送 1 form表单 RequestParam name String name 会把传递
  • React入门教程之井字棋(四)——时间旅行

    接下来是最后一个练习 我们将实现 回到过去 的功能 从而在游戏里跳回到历史步骤 保存历史记录 如果我们直接修改了 square 数组 实现时间旅行就会变得很棘手了 不过 我们可以使用 slice 函数为每一步创建 squares 数组的副本
  • Memcached的安装与基础语法

    Memcached Memcached 简介 Memcached是一个自由开源的 高性能 分布式内存对象缓存系统 Memcached简洁而强大 它的简洁设计便于快速开发 减轻开发难度 解决了大数据量缓存的很多问题 它的API兼容大部分流行的
  • JS校验数值

    JS校验数值的范围 大小及长度 function isInt str maxlen min max var pattern 0 1 9 d 非负整数 正整数 0 if str null str if pattern test str fal
  • 链接的请求方式 是get

    超链接的请求是get Get 是以实体的方式得到由请求URI所指定资源的信息 如果请求URI只是一个数据产生过程 那么最终要在响应实体中返回的是处理过程的结果所指向的资源 而不是处理过程的描述
  • win10下对编译完成后opencv_cuda进行移植

    系列文章目录 win10下Opencv源码编译支持CUDA加速的Python环境 超级详细教程 win10下对编译完成后opencv cuda进行移植 文章目录 系列文章目录 一 opencv python环境配置 二 opencv pyt
  • 01、虚拟机(VMware )部署

    一 VMware 概述 VMware是一家提供虚拟化解决方案的领先公司 其产品被广泛应用于企业和个人用户的计算环境中 VMware的虚拟化技术可以将物理计算资源 如服务器 存储和网络 抽象成虚拟化的资源 从而提供更高的灵活性 可扩展性和资源
  • Hbase Coprocessor 协处理器 与 JavaAPI

    协处理器概念 一 协处理器有两种 observer 和 endpoint 1 observer协处理器 Observer 类似于传统数据库中的触发器 当发生某些事件的时候这类协处理器会被 Server 端调用 Observer Coproc
  • 2021-08-26

    安装opencv python库 安装opencv python库 安装opencv python库 curl https bootstrap pypa io pip 2 7 get pip py o get pip py python g
  • 升级 Node 版本教程

    文章目录 Window 系统 Mac 或 Linux系统 Window 系统 window系统升级node只能到node官网下载window安装包来覆盖之前的node node 安装教程附下载地址 https blog csdn net q
  • selenium学习指南

    Selenium 是一套 Web网站 的程序自动化操作 解决方案 通过它 我们可以写出自动化程序 像人一样在浏览器里操作web界面 比如点击界面按钮 在文本框中输入文字 等操作 而且还能从web界面获取信息 比如获取火车 汽车票务信息 招聘
  • 使用Python,OpenCV制作图像Mask——截取ROIs及构建透明的叠加层

    使用Python OpenCV制作图像Mask 截取ROIs及构建透明的叠加层 1 效果图 2 源码 参考 这篇博客将介绍如何使用OpenCV制作Mask图像掩码 使用位运算和图像掩码允许我们只关注图像中感兴趣的部分 截取出任意区域的ROI
  • web自动化测试框架搭建(python+selenium+pytest+pom+ddt)

    本篇文件利用当下流行的pom设计模式设置测试框架 编写测试用例 生成测试报告 并最终jenkins集成 一 selenium selenium是一个开源的web ui自动化测试工具 详细就不再过多介绍了 二 环境搭建 关于环境搭建 非常简单
  • kubernetes使用ansible快速构建集群

    软硬件限制 1 cpu和内存 master 至少1c2g 推荐2c4g node 至少1c2g 2 linux系统 内核版本至少3 10 推荐CentOS7 RHEL7 3 docker 至少1 9版本 推荐1 12 4 etcd 至少2