1.基础系统配置

  • 2c/4g内存/40g硬盘(该配置仅测试用)
  • 最小化安装Ubuntu 16.04 server或者CentOS 7 Minimal
  • 配置基础网络、更新源、SSH登录等

    2.在每个节点安装依赖工具

    Ubuntu 16.04 请执行以下脚本:
    apt-get update && apt-get upgrade -y && apt-get dist-upgrade -y
    # 安装python2
    apt-get install python2.7
    # Ubuntu16.04可能需要配置以下软连接
    ln -s /usr/bin/python2.7 /usr/bin/python
    

3.在部署节点安装ansible及准备ssh免密登陆

  • 3.1 安装ansible (也可以使用容器化运行kubeasz,已经预装好ansible)
# 注意pip 21.0以后不再支持python2和python3.5,需要如下安装
# To install pip for Python 2.7 install it from https://bootstrap.pypa.io/2.7/ :
curl -O https://bootstrap.pypa.io/pip/2.7/get-pip.py    ### 根据网速决定
python get-pip.py
python -m pip install --upgrade "pip < 21.0"

# pip安装ansible(国内如果安装太慢可以直接用pip阿里云加速)
pip install ansible -i https://mirrors.aliyun.com/pypi/simple/

root@iZ0jl9tshllghi9199lnytZ:~# ansible --version    ### 查看安装是否成功

ssh-keygen     ## 一直敲回车
apt install sshpass   ## 安装脚本使需要的命令
root@iZ0jl9tshllghi9199lnytZ:~# sh ./ssh-scp.sh   ## 快速copy 密钥,实现免密钥验证

4.在部署节点编排k8s安装

  • 4.1 下载项目源码、二进制及离线镜像
# 下载工具脚本ezdown,举例使用kubeasz版本3.1.0
export release=3.1.0  ## 声明使用工具版本
wget https://github.com/easzlab/kubeasz/releases/download/${release}/ezdown
root@iZ0jl2xqw866y78tr0a4ttZ:~# vim ezdown
DOCKER_VER=19.03.15   ## 指定下载docker版本

chmod +x ./ezdown
# 使用工具脚本下载
root@iZ0jl2xqw866y78tr0a4ttZ:~# ./ezdown -D

上述脚本运行成功后,所有文件(kubeasz代码、二进制、离线镜像)均已整理好放入目录/etc/kubeasz

  • 4.2 创建集群配置实例 ```bash cd /etc/kubeasz ## 下载好的东西都在这里 root@iZ0jlipjlt4vahkg70fzghZ:/etc/kubeasz# ./ezctl new k8s-01 2022-05-22 22:12:32 DEBUG generate custom cluster files in /etc/kubeasz/clusters/k8s-01 2022-05-22 22:12:32 DEBUG set version of common plugins 2022-05-22 22:12:32 DEBUG cluster k8s-01: files successfully created. 2022-05-22 22:12:32 INFO next steps 1: to config ‘/etc/kubeasz/clusters/k8s-01/hosts’ ### 定义主机列表 2022-05-22 22:12:32 INFO next steps 2: to config ‘/etc/kubeasz/clusters/k8s-01/config.yml’

root@iZ0jl2xqw866y78tr0a4ttZ:/etc/kubeasz# vim /etc/kubeasz/clusters/k8s-01/hosts ### 定义主机列表 那些机器安装那些服务以及网络的规划

‘’’’’’ 1 # ‘etcd’ cluster should have odd member(s) (1,3,5,…) 2 [etcd] 3 172.24.181.41 4 5 # master node(s) 6 [kube_master] 7 172.24.181.38 8 9 # work node(s) 10 [kube_node] 11 172.24.181.39 12 172.24.181.40

19 # [optional] loadbalance for accessing k8s from outside 这里是master 节点高可用的vip地址,因为我是一个master、这里不写的话容易报错,所以我写了一个错误的地址 20 [ex_lb] 21 172.24.181.55 LB_ROLE=backup EX_APISERVER_VIP=172.24.181.56 EX_APISERVER_PORT=8443 22 172.24.181.54 LB_ROLE=master EX_APISERVER_VIP=172.24.181.56 EX_APISERVER_PORT=8443

36 # Network plugins supported: calico, flannel, kube-router, cilium, kube-ovn 37 CLUSTER_NETWORK=”flannel” ### 我这里是在阿里云部署,使用网络插件是flannel、因为云服务提供商网络策略不支持flannel,因此如果你是内网搭建的可以用calico

42 # K8S Service CIDR, not overlap with node(host) networking ### 不能和现有网络冲突 43 SERVICE_CIDR=”10.100.0.0/16” 44 45 # Cluster CIDR (Pod CIDR), not overlap with node(host) networking ### 不能和现有网络冲突 46 CLUSTER_CIDR=”10.200.0.0/16”

48 # NodePort Range 49 NODE_PORT_RANGE=”30000-60000” ### 暴露的端口范围,可以写大点

51 # Cluster DNS Domain 凡是创建的service 都是以这个结尾,当然你也可以保持默认 52 CLUSTER_DNS_DOMAIN=”magedu.local”

55 # Binaries Directory 存放二进制文件路径 56 bin_dir=”/usr/local/bin”

‘’’’’’

root@iZ0jl2xqw866y78tr0a4ttZ:/etc/kubeasz# vim /etc/kubeasz/clusters/k8s-01/config.yml ## 定义了那些服务和版本 比如dns和dashboard

‘’’’’

48 # [containerd]基础容器镜像 49 SANDBOX_IMAGE: “easzlab/pause-amd64:3.4.1” ### 提前把这个镜像下载下来

61 # [docker]信任的HTTP仓库
62 INSECURE_REG: ‘[“127.0.0.1/8”]’ #### 如果自己搭建的harbor 没有证书,可以把地址写在这里

86 # node节点最大pod 数 87 MAX_PODS: 300

174 # coredns 自动安装
175 dns_install: “no” ## 自己安装

177 ENABLE_LOCAL_DNS_CACHE: true

182 # metric server 自动安装 183 metricsserver_install: “no” ## 自己安装

186 # dashboard 自动安装 187 dashboard_install: “no” ## 自己安装

‘’’’’

至此修改的内容结束,接下来则是具体的安装部署

然后根据提示配置'/etc/kubeasz/clusters/k8s-01/hosts' 和 '/etc/kubeasz/clusters/k8s-01/config.yml:根据前面节点规划修改hosts 文件和其他集群层面的主要配置选项;其他集群组件等配置项可以在config.yml 文件中修改。

- 4.3 开始安装 如果你对集群安装流程不熟悉,请阅读项目首页 **安装步骤** 讲解后分步安装,并对 **每步都进行验证**


```bash
root@iZ0jl2xqw866y78tr0a4ttZ:/etc/kubeasz# ./ezctl help setup  ##查看安装顺序
Usage: ezctl setup <cluster> <step>
available steps:
    01  prepare            to prepare CA/certs & kubeconfig & other system settings 
    02  etcd               to setup the etcd cluster
    03  container-runtime  to setup the container runtime(docker or containerd)
    04  kube-master        to setup the master nodes
    05  kube-node          to setup the worker nodes
    06  network            to setup the network plugin
    07  cluster-addon      to setup other useful plugins
    90  all                to run 01~07 all at once
    10  ex-lb              to install external loadbalance for accessing k8s from outside
    11  harbor             to install a new harbor server or to integrate with an existed one

examples: ./ezctl setup test-k8s 01  (or ./ezctl setup test-k8s prepare)
      ./ezctl setup test-k8s 02  (or ./ezctl setup test-k8s etcd)
          ./ezctl setup test-k8s all
          ./ezctl setup test-k8s 04 -t restart_master

root@iZ0jl2xqw866y78tr0a4ttZ:/etc/kubeasz# ./ezctl setup k8s-01 01

fatal: [172.24.181.55]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 172.24.181.55 port 22: Connection timed out", "unreachable": true}
fatal: [172.24.181.54]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 172.24.181.54 port 22: Connection timed out", "unreachable": true}

#### 解决方法
root@iZ0jl2xqw866y78tr0a4ttZ:/etc/kubeasz# vim playbooks/01.prepare.yml
- ex_lb       ## 删除这个即可

重新执行
root@iZ0jl2xqw866y78tr0a4ttZ:/etc/kubeasz# ./ezctl setup k8s-01 01

02-安装etcd集群

root@iZ0jl2xqw866y78tr0a4ttZ:/etc/kubeasz# ./ezctl setup k8s-01 02   # 安装etcd

验证etcd集群状态

  • systemctl status etcd 查看服务状态
  • journalctl -u etcd 查看运行日志
  • 在任一 etcd 集群节点上执行如下命令

    我是部署的单节点etcd 可以使用systemctl status etcd 查看服务状态, 如果你是部署的etcd 机器执行以下命令

    # 根据hosts中配置设置shell变量 $NODE_IPS
    export NODE_IPS="192.168.1.1 192.168.1.2 192.168.1.3"
    for ip in ${NODE_IPS}; do
    ETCDCTL_API=3 etcdctl \
    --endpoints=https://${ip}:2379  \
    --cacert=/etc/kubernetes/ssl/ca.pem \
    --cert=/etc/etcd/ssl/etcd.pem \
    --key=/etc/etcd/ssl/etcd-key.pem \
    endpoint health; done
    

    预期结果:

    https://192.168.1.1:2379 is healthy: successfully committed proposal: took = 2.210885ms
    https://192.168.1.2:2379 is healthy: successfully committed proposal: took = 2.784043ms
    https://192.168.1.3:2379 is healthy: successfully committed proposal: took = 3.275709ms
    

    三台 etcd 的输出均为 healthy 时表示集群服务正常。

单节点结果:

root@iZ0jl2xqw866y78tr0a4tsZ:~# systemctl status etcd
● etcd.service - Etcd Server
   Loaded: loaded (/etc/systemd/system/etcd.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2022-05-23 23:13:38 CST; 6min ago
     Docs: https://github.com/coreos
 Main PID: 6622 (etcd)
   CGroup: /system.slice/etcd.service
           └─6622 /usr/local/bin/etcd --name=etcd-172.24.181.41 --cert-file=/etc/kubernetes/ssl/etcd.pem --key-file=/etc/kubernetes/ssl/etcd-key.pem --peer-cert-file=/etc/k

May 23 23:13:38 iZ0jl2xqw866y78tr0a4tsZ etcd[6622]: raft2022/05/23 23:13:38 INFO: raft.node: 1e065d6f495b9ac3 elected leader 1e065d6f495b9ac3 at term 2
May 23 23:13:38 iZ0jl2xqw866y78tr0a4tsZ etcd[6622]: published {Name:etcd-172.24.181.41 ClientURLs:[https://172.24.181.41:2379]} to cluster d3a902f564a78360
May 23 23:13:38 iZ0jl2xqw866y78tr0a4tsZ etcd[6622]: ready to serve client requests
May 23 23:13:38 iZ0jl2xqw866y78tr0a4tsZ etcd[6622]: setting up the initial cluster version to 3.4
May 23 23:13:38 iZ0jl2xqw866y78tr0a4tsZ etcd[6622]: ready to serve client requests
May 23 23:13:38 iZ0jl2xqw866y78tr0a4tsZ systemd[1]: Started Etcd Server.
May 23 23:13:38 iZ0jl2xqw866y78tr0a4tsZ etcd[6622]: serving insecure client requests on 127.0.0.1:2379, this is strongly discouraged!
May 23 23:13:38 iZ0jl2xqw866y78tr0a4tsZ etcd[6622]: serving client requests on 172.24.181.41:2379
May 23 23:13:38 iZ0jl2xqw866y78tr0a4tsZ etcd[6622]: set the initial cluster version to 3.4
May 23 23:13:38 iZ0jl2xqw866y78tr0a4tsZ etcd[6622]: enabled capabilities for version 3.4

03-安装容器运行时(docker or containerd)

root@iZ0jl2xqw866y78tr0a4ttZ:/etc/kubeasz# ./ezctl setup k8s-01 03

验证

安装成功后验证如下:

systemctl status docker     # 服务状态
journalctl -u docker         # 运行日志
docker version
docker info

04-安装kube_master节点

部署master节点主要包含三个组件apiserver scheduler controller-manager,其中:

  • apiserver提供集群管理的REST API接口,包括认证授权、数据校验以及集群状态变更等
    • 只有API Server才直接操作etcd
    • 其他模块通过API Server查询或修改数据
    • 提供其他模块之间的数据交互和通信的枢纽
  • scheduler负责分配调度Pod到集群内的node节点
    • 监听kube-apiserver,查询还未分配Node的Pod
    • 根据调度策略为这些Pod分配节点
  • controller-manager由一系列的控制器组成,它通过apiserver监控整个集群的状态,并确保集群处于预期的工作状态

    高可用机制

  • apiserver 无状态服务,可以通过外部负载均衡实现高可用,如项目采用的两种高可用架构:HA-1x (#584)和 HA-2x (#585)

  • controller-manager 组件启动时会进行类似选举(leader);当多副本存在时,如果原先leader挂掉,那么会选举出新的leader,从而保证高可用;
  • scheduler 类似选举机制
    root@iZ0jl2xqw866y78tr0a4ttZ:/etc/kubeasz# ./ezctl setup k8s-01 04
    

master 集群的验证

运行./ezctl setup k8s-01 04 成功后,验证 master节点的主要组件:

# 查看进程状态
systemctl status kube-apiserver
systemctl status kube-controller-manager
systemctl status kube-scheduler
# 查看进程运行日志
journalctl -u kube-apiserver
journalctl -u kube-controller-manager
journalctl -u kube-scheduler

执行 kubectl get componentstatus 可以看到

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

05-安装kube_node节点

kube_node 是集群中运行工作负载的节点,前置条件需要先部署好kube_master节点,它需要部署如下组件:

  • kubelet: kube_node上最主要的组件
  • kube-proxy: 发布应用服务与负载均衡
  • haproxy:用于请求转发到多个 apiserver,
  • calico: 配置容器网络 (或者其他网络组件)

    创建cni 基础网络插件配置文件

    因为后续需要用 DaemonSet Pod方式运行k8s网络插件,所以kubelet.server服务必须开启cni相关参数,并且提供cni网络配置文件
root@iZ0jl2xqw866y78tr0a4ttZ:/etc/kubeasz# ./ezctl setup k8s-01 05

验证 node 状态

systemctl status kubelet    # 查看状态
systemctl status kube-proxy
journalctl -u kubelet        # 查看日志
journalctl -u kube-proxy

运行 kubectl get node 可以看到类似

root@iZ0jl2xqw866y78tr0a4ttZ:/etc/kubeasz# kubectl get node
NAME            STATUS   ROLES   AGE     VERSION
172.24.181.38   Ready    node    7m50s   v1.21.0
172.24.181.39   Ready    node    88s     v1.21.0
172.24.181.40   Ready    node    88s     v1.21.0

06-安装网络组件

首先回顾下K8S网络设计原则,在配置集群网络插件或者实践K8S 应用/服务部署请时刻想到这些原则:

  • 1.每个Pod都拥有一个独立IP地址,Pod内所有容器共享一个网络命名空间
  • 2.集群内所有Pod都在一个直接连通的扁平网络中,可通过IP直接访问
    • 所有容器之间无需NAT就可以直接互相访问
    • 所有Node和所有容器之间无需NAT就可以直接互相访问
    • 容器自己看到的IP跟其他容器看到的一样
  • 3.Service cluster IP尽可在集群内部访问,外部请求需要通过NodePort、LoadBalance或者Ingress来访问

Container Network Interface (CNI)是目前CNCF主推的网络模型,它由两部分组成:

  • CNI Plugin负责给容器配置网络,它包括两个基本的接口
    • 配置网络: AddNetwork(net NetworkConfig, rt RuntimeConf) (types.Result, error)
    • 清理网络: DelNetwork(net NetworkConfig, rt RuntimeConf) error
  • IPAM Plugin负责给容器分配IP地址

Kubernetes Pod的网络是这样创建的:

  • 0.每个Pod除了创建时指定的容器外,都有一个kubelet启动时指定的基础容器,比如:easzlab/pause registry.access.redhat.com/rhel7/pod-infrastructure
  • 1.首先 kubelet创建基础容器生成network namespace
  • 2.然后 kubelet调用网络CNI driver,由它根据配置调用具体的CNI 插件
  • 3.然后 CNI 插件给基础容器配置网络
  • 4.最后 Pod 中其他的容器共享使用基础容器的网络

本项目基于CNI driver 调用各种网络插件来配置kubernetes的网络,常用CNI插件有 flannel calico weave等等,这些插件各有优势,也在互相借鉴学习优点,比如:在所有node节点都在一个二层网络时候,flannel提供hostgw实现,避免vxlan实现的udp封装开销,估计是目前最高效的;calico也针对L3 Fabric,推出了IPinIP的选项,利用了GRE隧道封装;因此这些插件都能适合很多实际应用场景。
项目当前内置支持的网络插件有:calico cilium flannel kube-ovn kube-router

我安装的是flannel,在etc/kubeasz/clusters/k8s-01/hosts 已经定义好了

root@iZ0jl2xqw866y78tr0a4ttZ:/etc/kubeasz# ./ezctl setup k8s-01 06

安装 flannel网络

  • 安装之前必须确保kube_master和kube_node节点已经成功部署
  • 只需要在任意装有kubectl客户端的节点运行 kubectl create安装即可
  • 等待15s后(视网络拉取相关镜像速度),flannel 网络插件安装完成,删除之前kube_node安装时默认cni网络配置

    验证flannel网络

    执行flannel安装成功后可以验证如下:(需要等待镜像下载完成,有时候即便上一步已经配置了docker国内加速,还是可能比较慢,请确认以下容器运行起来以后,再执行后续验证步骤)
    # kubectl get pod --all-namespaces
    NAMESPACE     NAME                    READY     STATUS    RESTARTS   AGE
    kube-system   kube-flannel-ds-m8mzm   1/1       Running   0          3m
    kube-system   kube-flannel-ds-mnj6j   1/1       Running   0          3m
    kube-system   kube-flannel-ds-mxn6k   1/1       Running   0          3m
    
    在集群创建几个测试pod: ```bash kubectl run net-test —image=busybox sleep 30000 kubectl run net-test2 —image=busybox sleep 30000 kubectl run net-test3 —image=busybox sleep 30000

root@iZ0jl2xqw866y78tr0a4ttZ:/etc/kubeasz# kubectl get pod -A -o wide NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES default net-test 1/1 Running 0 81s 10.200.0.2 172.24.181.38 default net-test2 1/1 Running 0 74s 10.200.2.2 172.24.181.39 default net-test3 1/1 Running 0 69s 10.200.1.2 172.24.181.40 kube-system kube-flannel-ds-amd64-5vkh2 1/1 Running 0 5m10s 172.24.181.40 172.24.181.40 kube-system kube-flannel-ds-amd64-5xktv 1/1 Running 0 5m10s 172.24.181.38 172.24.181.38 kube-system kube-flannel-ds-amd64-l5gh4 1/1 Running 0 5m10s 172.24.181.39 172.24.181.39

root@iZ0jl2xqw866y78tr0a4ttZ:/etc/kubeasz# kubectl exec -it net-test sh

/ # ping -c2 10.200.2.2 ### net-test2 地址 PING 10.200.2.2 (10.200.2.2): 56 data bytes 64 bytes from 10.200.2.2: seq=0 ttl=62 time=0.299 ms 64 bytes from 10.200.2.2: seq=1 ttl=62 time=0.232 ms

/ # ping -c2 10.200.1.2 ### net-test3 地址 PING 10.200.1.2 (10.200.1.2): 56 data bytes 64 bytes from 10.200.1.2: seq=0 ttl=62 time=0.401 ms 64 bytes from 10.200.1.2: seq=1 ttl=62 time=0.259 ms

<a name="VBzRR"></a>
### 安装 coredns网络

- 提前将 coredns-image-v1.8.3.tar.gz 下载下来,并导入
```bash
docker load -i coredns-image-v1.8.3.tar.gz    
kubectl apply -f coredns.yaml
kubectl get pod -A  ## 查看pod 是否启动
kube-system            coredns-8664b5df7c-vph7q                     1/1     Running   0          56m

安装dashboard

kubectl apply -f dashboard-v2.3.1.yaml
kubectl get pod -A

kubernetes-dashboard   dashboard-metrics-scraper-856586f554-snfh5   1/1     Running   0          49m
kubernetes-dashboard   kubernetes-dashboard-79b875f7f8-s5pm7        1/1     Running   0          49m
  • 创建用户并登陆

    more admin-user.yml ```yaml apiVersion: v1 kind: ServiceAccount metadata: name: admin-user namespace: kubernetes-dashboard


apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: admin-user roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects:

  • kind: ServiceAccount name: admin-user namespace: kubernetes-dashboard ```

  • 查看用户并登陆dashboard界面 端口30002 ```yaml kubectl apply -f admin-user.yml

root@iZ0jl9oh0b64affk7480r5Z:~# kubectl get secrets -A | grep admin kubernetes-dashboard admin-user-token-ftrmk kubernetes.io/service-account-token 3 50m

kubectl describe secrets admin-user-token-ftrmk -n kubernetes-dashboard ```