
# 部署Kubernetes集群
#### 软件版本
- 系统： Centos 7.7
- Kernel Version： 4.18.9-1.el7.elrepo.x86_64
- Kubernetes： v1.19.16
- calico: v3.19.1
- docker-ce: 20.10.12
- VIP: 内网负载均衡
#### 服务器清单
表1服务器清单 
| **序号** | **IP**        | **主机名**     | **部署描述** |
|:---|:---|:---|:---|
| 1      | 192.168.1.61  | k8s-master1 | k8s管理节点  |
| 2      | 192.168.1.195 | k8s-master2 | k8s管理节点  |
| 3      | 192.168.1.198 | k8s-master3 | k8s管理节点  |
| 4      | 192.168.1.207 | k8s-node01  | k8s工作节点  |
| 5      | 192.168.1.237 | k8s-node02  | k8s工作节点  |
| 6      | 192.168.1.235 | k8s-node03  | k8s工作节点  |
| 7      | 192.168.1.199 | k8s-node04  | k8s工作节点  |
| 8      | 192.168.1.191 | k8s-node05  | k8s工作节点  |
| 9      | 192.168.1.189 | k8s-node06  | k8s工作节点  |
| 10     | 192.168.1.57  | k8s-node07  | k8s工作节点  |
| 11     | 192.168.1.133 | k8s-node08  | k8s工作节点  |
| 12     | 192.168.1.127 | k8s-node09  | k8s工作节点  |
| 13     | 192.168.1.82  | k8s-node10  | k8s工作节点  |
| 14     | 192.168.1.156 | k8s-node11  | k8s工作节点  |
   
#### 优化kubernetes集群
- 关闭swap
  ```
  ansible k8smaster -m shell -a "swapoff -a  &&  sed -ri 's/.*swap.*/#&/' /etc/fstab"
  ```
  
- 优化服务器内核参数
  1. 脚本
     ```
     ##优化内核参数，文件k8s.conf、limits.conf在部署文件夹内
     ---
     - name:  config sysctl
     hosts: k8s
     tasks:
     - name: copy sysctl kernel argus
     copy: src=/etc/ansible/k8s.conf dest=/etc/sysctl.d/
     - name:
     shell : sysctl --system
     - name: config limit
     copy: src=/etc/ansible/limits.conf dest=/etc/security/limits.conf
     ```
     
  
  2. 执行
     ```
     ansible-playbook sysctl_config.yaml
     ```
     
  
  3. 验证
     ```
     ansible k8smaster -m shell -a "sysctl --system"
     ```
     
   
- 开启ip_vs模块
  1. 脚本
     ```
     ##k8s集群使用ip_VS模式，能大大提高性能，减少iptables规则数量
     ---
     - name: start ipvs module
     hosts: k8s
     tasks:
     - name:
     shell : modprobe -- ip_vs && modprobe -- ip_vs_rr && modprobe -- ip_vs_wrr && modprobe -- ip_vs_sh && modprobe -- nf_conntrack_ipv4
     ```
     
  
  2. 执行脚本
     ```
     ansible-playbook ipvs.yaml
     ```
     
  
  3. 验证
     ```
     ansible  k8s -m shell -a "lsmod | grep ip_vs"
     ```
     图1验证4   
     ![](https://support.huaweicloud.com/tsecp-education/zh-cn_image_0000001873413162.png)
     ```
     Figure4:
     ```
     
   
 
#### 启动docker
- 准备启动脚本
  ```
  ---
  - name: start docker-ce
  hosts: k8smaster
  tasks:
  - name: make docker daemon directory  ##创建镜像加速、配置目录
  file: path=/etc/docker/  state=directory
  - name: copy docker daemon.json file  ##此文件内容见下方
  copy: src=/etc/docker/daemon.json dest=/etc/docker/daemon.json
  - name: Support docker tab key completion  ##支持docker使用tab键命令补全功能
  shell: source /usr/share/bash-completion/completions/docker && source /usr/share/bash-completion/bash_completion
  - name: support kubeadm kubectl tab key completion ##支持kubectl、kubeadm使用tab键命令补全功能
  shell: echo 'source <(kubectl completion bash)' >> /root/.bashrc \
  && source /root/.bashrc
  - name: start docker  ##启动docker容器
  service: name=docker state=started enabled=yes
  - name: enable kubelet  ##kubelet开机自启，初始化kubernetes必须执行此操作
  shell : systemctl enable kubelet
  ```
  
  附： deamon.json文件内容：
  ```
  {
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {   ##docker日志本地保存策略，保存500m，每个容器保存5个日志文件
  "max-size": "500m",
  "max-file": "5"
  },
  "storage-driver": "overlay2",
  "storage-opts": [
  "overlay2.override_kernel_check=TRUE"
  ],
  "registry-mirrors":["https://r2hd8p9u.mirror.aliyuncs.com"],
  "data-root": "/data/docker"   ##使用/data/docker作为docker根路径
  }
  ```
  
- 执行脚本
  ```
  ansible-playbook startdocker.yaml
  ```
  
- 验证
  ```
  ansible k8s -m shell -a "systemctl status docker "
  ```
  图2验证5   
  ![](https://support.huaweicloud.com/tsecp-education/zh-cn_image_0000001873254508.png)
  ```
  Figure5:
  ```
  
#### 集群初始化(此步骤在master01上执行)
- 准备kubeadm初始化文件
  ```
  cat  >> kubeadm-config.yaml << EOF
  apiVersion: kubeadm.k8s.io/v1beta2
  bootstrapTokens:
  - groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
  kind: InitConfiguration
  localAPIEndpoint:
  advertiseAddress: 192.168.1.61
  bindPort: 6443
  nodeRegistration:
  criSocket: /var/run/dockershim.sock
  name: nx-master01
  taints:
  - effect: NoSchedule
  key: node-role.kubernetes.io/master
  ---
  apiServer:
  timeoutForControlPlane: 4m0s
  apiVersion: kubeadm.k8s.io/v1beta2
  certificatesDir: /etc/kubernetes/pki
  clusterName: kubernetes
  controllerManager: {}
  controlPlaneEndpoint: "k8s.talkedu.com:6443"   ##kube-apiserver使用IP，为内网负载均衡器IP
  dns:
  type: CoreDNS
  etcd:
  local:
  dataDir: /var/lib/etcd
  imageRepository: harbor.talkedu.com/system  ##使用镜像仓库下载镜像
  kind: ClusterConfiguration
  kubernetesVersion: v1.19.16  ##部署版本为1.19.3
  networking:
  dnsDomain: cluster.local
  serviceSubnet: "10.96.0.0/12"
  podSubnet: "10.244.0.0/16"   ##pod网段，此字段需与calico网段保持一致
  scheduler: {}
  ---
  apiVersion: kubeproxy.config.k8s.io/v1alpha1
  kind: KubeProxyConfiguration   ###集群使用ipvs作为网络模式
  mode: "ipvs"
  EOF
  ```
  
- 开始初始化kubeadm控制平面
  ```
  kubeadm init --config=kubeadm-config.yaml --upload-certs
  ```
  
- 保存加入集群命令 将上面命令打印的kubeadm join命令保存，后续控制平面和数据平面加入集群时需要用到。
  
- 配置kubectl访问集群配置文件
  ```
  ## 配置kubectl命令管理kubernetes集群
  mkdir /root/.kube && cp /etc/kubernetes/admin.conf  /root/.kube/config
  ```
  
- 验证
  ```
  kubectl get node && kubectl get pods -n kube-system
  ```
  图3验证6   
  ![](https://support.huaweicloud.com/tsecp-education/zh-cn_image_0000001919529857.png)
  ```
  Figure6:
  ```
  图4验证7   
  ![](https://support.huaweicloud.com/tsecp-education/zh-cn_image_0000001919649521.png)
  ```
  Figure7:
  ```
  
#### 安装calico网络插件
- 准备安装清单文件
  ```
  calico.yaml ##此文件在部署文件内
  ```
  
- 应用清单文件
  ```
  kubectl apply -f calico.yaml
  ```
  
- 验证
  ```
  kubectl get pods -n kube-system   ##查看次名称空间内所有Pod是否成功启动
  ```
  图5验证8   
  ![](https://support.huaweicloud.com/tsecp-education/zh-cn_image_0000001919531557.png)
  ```
  Figure8:
  ```
  
#### 将其余master节点和node节点加入集群
- 在master节点上执行
  ```
  kubeadm join k8s.talkedu.com:6443 --token abcdef.0123456789abcdef \
  --discovery-token-ca-cert-hash sha256:1df03bef705ad54fa693121e644d372d37d6b7e79a45058a999bc2d2ff590776 \
  --control-plane --certificate-key 8bbe0725b691eff7ea4e92b4ef70a797ce3224a84e8ad8c02c42e70b32de3df0
  ##此命令仅24小时内有效，过期需重新打印加入集群指令,执行命令为： kubeadm token create --print-join-command
  ```
  
- 在node节点上执行
  ```
  kubeadm join k8s.talkedu.com:6443 --token abcdef.0123456789abcdef \
  --discovery-token-ca-cert-hash sha256:1df03bef705ad54fa693121e644d372d37d6b7e79a45058a999bc2d2ff590776
  ##此命令仅24小时内有效，过期需重新打印加入集群指令，执行命令为： kubeadm token create --print-join-command
  ```
  
- 验证
  ```
  kubectl get nodes && kubectl get pods -A
  ```
  
#### 更新证书有效期10年
- 准备更新脚本
  ```
  update-kubeadm-cert.sh ##此文件在部署文件内，kubernetes集群默认证书有效期为1年
  ```
  
- 执行脚本
  ```
  bash update-kubeadm-cert.sh all
  ## 此脚本能更新除kubelet之外的所有证书
  ```
  
- 验证
  ```
  kubeadm alpha certs check-expiration
  ```
  图6验证9   
  ![](https://support.huaweicloud.com/tsecp-education/zh-cn_image_0000001919783973.png)
  ```
  Figure9:
  ```
  
- 升级kubelet证书
  ```
  ##在kube-controller-manager配置文件中，在command内添加最后两行，配置更新证书期限为10年，并开启证书自动轮转
  vim /etc/kubernetes/manifests/kube-controller-manager.yaml
  - command:
  - kube-controller-manager
  - --experimental-cluster-signing-duration=87600h0m0s
  - --feature-gates=RotateKubeletServerCertificate=TRUE
  ```
  重启kubelet服务
  ```
  systemctl restart kubelet
  ```
  
#### 部署ingress-nginx
提供对外访问入口，将此服务的80、443端口映射到主机上，访问时，通过该80、443端口，访问集群内所有服务。
- 准备安装清单文件
  ```
  ingress-nginx.yaml ##此文件在部署文件内
  ```
  
- 应用清单文件
  ```
  kubectl apply -f  ingress-nginx.yaml
  ```
  
- 验证
  ```
  kubectl  get pods -n ingress-nginx
  ```
  图7验证10   
  ![](https://support.huaweicloud.com/tsecp-education/zh-cn_image_0000001919664293.png)
  ```
  Figure10:
  ```
  
 
