TH小破站

  • 首页
  • 容器
    • 认识Docker
    • DockerFile详解
  • k8s
    • 认识Kubernetes
    • Kubernetes部署--(kubeadm方式)
    • kubeasz部署k8s集群
    • Ansible-binary部署k8s集群-1.31.2
  • Ceph
    • 认识分布式存储
    • CPEH部署
  • CI/CD
    • DevOps认识
    • 部署--Gitlab
  • ELK
    • ELK简介
    • Elasticsearch
    • Kibana部署
    • Logstash
    • ELK--收集 tomcat 日志(实战)
  • HD
    • 认识--大数据
    • Hadoop-单机部署
    • Hadoop-伪分布部署
    • Hadoop-完全分布部署
    • Hadoop-(HA)完全分布部署
    • Ambari自动部署--Hadoop
  • Nginx
    • Nginx功能介绍
    • Nginx安全选项
    • Nginx配置文件简单介绍
    • 网站服务器部署
  • 监控
    • ZABBIX-部署(yum)
    • ZABBIX-编译安装
  • 云计算
    • KVM 概述
    • OpenStack企业级部署(T版)
    • OpenStack之dashboard部署
    • OpenStack-controller的高可用
    • openstack(Caracal版_ubuntu版本)部署
  • 数据库
    • mariadb与mysql
    • mysql主从
    • MySQL--冷备(实战)
    • MySQL--热备(dump表)
    • MySQL--热备(dump库)
    • 数据恢复实战案例
    • Xtrabackup实现MySql8.x全量备份
    • MyCat实现数据库读写分离
    • MHA实现数据库高可用
    • Percona XtraDB(PXC)实现数据库集群高可用
    • 数据库压力测试
    • PostgreSQL 基操
    • PostgreSQL备份恢复
    • PostgreSQL高可用
    • MongDB安装配置基础使用
    • MongoDB实现复制集
    • MongoDB备份还原
  • 自动化
    • ssh远程服务原理及配置
    • Ansible剧本文件应用
    • Ansible管理服务介绍
    • Ansible自动化部署node_exporter(包含升级,回滚)
    • Saltstack-部署安装
  • 脚本
    • 一键查看服务器资源利用率
    • 一键生成SSL证书
    • 保存指定数量的文件/目录
    • 初始化服务器
    • 扫描可用IP
    • 批量分发SSH密钥
    • 监控多主机磁盘脚本
    • 一键安装MySQL8.x脚本
    • Python脚本监控ES集群
    • 资源巡检脚本
    • 查看各用户使用的cpu占比
热衷于分享
架构师成长之路 !!!

Ansible-binary部署k8s集群-1.31.2

二进制部署K8S

架构

主机名 IP VIP 域名
master-01 192.168.139.121
master-02 192.168.139.122
master-03 192.168.139.123
node-01 192.168.139.124
node-02 192.168.139.125
haproxy(部署服务器) 192.168.139.36 192.168.139.248 k8s-api.stangj.io
harbor 192.168.139.100 harbor.stangj.com

1.)前期准备

1.1)所有节点执行

 ~# sed -i 's/^\/swap.*$/#&/g' /etc/fstab
 `列出swap设备`
 ~# systemctl --type swap
 ...
   UNIT          LOAD   ACTIVE SUB    DESCRIPTION
   swap.img.swap loaded active active /swap.img
 ...
 `关闭swap设备`
 ~# systemctl mask swap.img.swap
 ~# swapoff -a
 ​
 ~# modprobe br_netfilter
 ~# echo "br_netfilter" | sudo tee /etc/modules-load.d/br_netfilter.conf
 ~# echo -e  "net.bridge.bridge-nf-call-iptables = 1\nnet.ipv4.ip_forward = 1" >> /etc/sysctl.conf
 ~# sysctl -p
 _# echo -e '192.168.139.248 k8s-api.stangj.io\n192.168.139.100 harbor.stangj.com' >> /etc/hosts

1.2)时间同步(选做)

 "时间同步服务器我这里用的 master-01"
 ~# apt install chrony -y
 ~# cat  /etc/chrony/chrony.conf  | grep -vE "^#|^$"
 confdir /etc/chrony/conf.d
 server ntp1.aliyun.com iburst
 server ntp2.aliyun.com iburst
 server ntp3.aliyun.com iburst
 allow 192.168.139.0/24
 local stratum 10
 sourcedir /run/chrony-dhcp
 sourcedir /etc/chrony/sources.d
 keyfile /etc/chrony/chrony.keys
 driftfile /var/lib/chrony/chrony.drift
 ntsdumpdir /var/lib/chrony
 logdir /var/log/chrony
 maxupdateskew 100.0
 rtcsync
 makestep 1 3
 ​
 `启动服务`
 ~# systemctl enable chrony && systemctl restart chrony
 ​
 `验证`
 ~# chronyc sources
 210 Number of sources = 2
 MS Name/IP address         Stratum Poll Reach LastRx Last sample               
 ===============================================================================
 ^- 120.25.115.20                 2   6    35    48   +866us[ +866us] +/-   22ms
 ^* 203.107.6.88                  2   6    17    49  -4324us[-9570us] +/-   21ms
 ​
 "其他节点配置(集群涉及到的节点都要配置--我演示一个)"
 ~# apt install chrony -y
 ~#  vim   /etc/chrony/chrony.conf 
 #server 0.centos.pool.ntp.org iburst
 #server 1.centos.pool.ntp.org iburst
 #server 2.centos.pool.ntp.org iburst
 #server 3.centos.pool.ntp.org iburst
 server 192.168.139.121 iburst   # 添加这条信息指向controller1
 r~# systemctl restart chrony &&systemctl enable --now chrony
 ~# chronyc sources
 210 Number of sources = 1
 MS Name/IP address         Stratum Poll Reach LastRx Last sample               
 ===============================================================================
 ^* 192.168.139.31                3   6    37    60  -2089ns[ -943us] +/-   16ms

1.3)haproxy准备

harbor下载地址:https://github.com/goharbor/harbor/releases/tag/v2.5.4

 root@haproxy:~# apt install haproxy
 root@haproxy:~# apt -y install keepalived
 `配置keepalived`
 root@haproxy:~# vim /etc/keepalived/keepalived.conf 
 global_defs {
    smtp_connect_timeout 30
    router_id LVS_DEVEL
    vrrp_skip_check_adv_addr
    vrrp_iptables
    vrrp_garp_interval 0
    vrrp_gna_interval 0
 }
 ​
 vrrp_instance VI_1 {
     state MASTER
     interface eth0
     virtual_router_id 51
     priority 100
     advert_int 1
     authentication {
         auth_type PASS
         auth_pass 1111
     }
     virtual_ipaddress {
         192.168.139.248 dev eth0 label eth0:0
     }
 }
 root@haproxy:~# systemctl enable --now keepalived.service 
 root@haproxy:~# systemctl restart keepalived.service 
 root@haproxy:~# echo -e 'net.ipv4.ip_nonlocal_bind = 1\nnet.ipv4.ip_forward = 1' >> /etc/sysctl.conf 
 root@haproxy:~# sysctl -p
 root@haproxy:~# cat /etc/haproxy/haproxy.cfg
 ......# 最后添加下面 6 行
 listen k8s-api-node
   bind 192.168.139.248:6443
   mode tcp
   server 192.168.139.121 192.168.139.121:6443 check inter 3s fall 3 rise 5
   server 192.168.139.122 192.168.139.122:6443 check inter 3s fall 3 rise 5
   server 192.168.139.123 192.168.139.123:6443 check inter 3s fall 3 rise 5
 root@haproxy:~# systemctl enable --now haproxy.service 
 root@haproxy:~# systemctl restart haproxy.service 

1.4)harbor仓库准备

安装仓库

harbor下载地址:https://github.com/goharbor/harbor/releases/tag/v2.5.6

 root@harbor:~# docker --version
 Docker version 27.0.3, build 7d4bcd8
 root@harbor:~# docker-compose version
 Docker Compose version v2.22.0
 root@harbor:~# mkdir /apps
 root@harbor:~# tar xf harbor-offline-installer-v2.5.6.tgz -C /apps/
 root@harbor:~# cd /apps/harbor/
 root@harbor:/apps/harbor# cp harbor.yml.tmpl harbor.yml
 root@harbor:/apps/harbor# grep -Ev '^#|^$|#'  harbor.yml
 ......
 hostname: harbor.stangj.com
 http:
   port: 80
 harbor_admin_password: 123456
 database:
   password: root123
   max_idle_conns: 100
   max_open_conns: 900
 data_volume: /data
 .....
 `部署安装`
 root@harbor:/apps/harbor# ./install.sh --with-trivy --with-chartmuseum

http://harbor.stangj.com/

登录验证仓库

 root@harbor:/apps/harbor# docker login  harbor.stangj.com
 Username: admin
 Password: 
 Error response from daemon: Get "https://harbor.stangj.com/v2/": tls: failed to verify certificate: x509: certificate is valid for www.stangj.com, stangj.com, not harbor.stangj.com
 # 登录出错 因为没有lts证书 不安全
 `docker配置不安全仓库认证`
 root@harbor:/apps/harbor# vim /etc/docker/daemon.json 
 {
 "registry-mirrors": [
  "https://docker.m.daocloud.io",
  "https://dockerhub.timeweb.cloud",
  "https://huecker.io",
  "https://gigi8vhp.mirror.aliyuncs.com"
 ],
 "insecure-registries": [
   "harbor.stangj.com"    # 将不需要tls认证的域名放这里
 ],
 "exec-opts": ["native.cgroupdriver=systemd"],
 "log-driver": "json-file",
 "log-opts": {
 "max-size": "200m"
 },
 "storage-driver": "overlay2"
 }
 root@harbor:/apps/harbor# systemctl restart docker
 ​
 `Containerd配置不安全仓库认证`
 [plugins."io.containerd.grpc.v1.cri".registry]
   [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
      [plugins."io.containerd.grpc.v1.cri".registry.mirrors."harbor.stangj.com"]
        endpoint = ["https://harbor.stangj.com"]
   [plugins."io.containerd.grpc.v1.cri".registry.configs]
      [plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.stangj.com".tls] # 这里配置对于域名
        insecure_skip_verify = true
      [plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.stangj.com".auth]
        username = "admin"
        password = "123456"
 ~# systemctl daemon-reload 
 ~# systemctl restart containerd 
 ​
 `登录`
 root@harbor:/apps/harbor# docker login  harbor.stangj.com
 Username: admin
 Password: 
 WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
 Configure a credential helper to remove this warning. See
 https://docs.docker.com/engine/reference/commandline/login/#credential-stores
 ​
 Login Succeeded

注意:生产环境是要对harbor仓库配置 tls 证书,我们可以在前面用 nginx 反向代理到 harbor ,证书统一在nginx侧管理

2.)部署节点初始化

部署节点配置

 1root@haproxy:/usr/local/src# echo '192.168.139.100 harbor.stangj.com' >> /etc/hosts
 root@haproxy:/usr/local/src# bash runtime-install.sh docker
 root@haproxy:/usr/local/src# docker login harbor.stangj.com
 Username: admin
 Password: 
 WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
 Configure a credential helper to remove this warning. See
 https://docs.docker.com/engine/reference/commandline/login/#credentials-store
 ​
 Login Succeeded
 root@haproxy:/usr/local/src# docker pull registry.cn-zhangjiakou.aliyuncs.com/tanghao429/tanghao:demoapp:v1.0
 root@openstack-haproxy:~# docker push harbor.stangj.com/baseimage/demoapp:v1.0
 The push refers to repository [harbor.stangj.com/baseimage/demoapp]
 5a4de022ffa3: Pushed 
 cc619f457978: Pushed 
 318b2baca508: Pushed 
 5216338b40a7: Pushed 
 v1.0: digest: sha256:6698b205eb18fb0171398927f3a35fe27676c6bf5757ef57a35a4b055badf2c3 size: 1159

免秘钥登录配置

 root@haproxy:~# apt install ansible sshpass
 root@haproxy:~# ssh-keygen -t rsa-sha2-512 -b 4096
 root@haproxy:~#vim key-scp.sh
 #!/bin/bash
 IP="
 192.168.139.121
 192.168.139.122
 192.168.139.123
 192.168.139.124
 192.168.139.125
 "
 REMOTE_PORT="22"
 REMOTE_USER="root"
 REMOTE_PASS="123456"
 for REMOTE_HOST in ${IP};do
     REMOTE_CMD="echo ${REMOTE_HOST} is successfully!"
     #添加⽬标远程主机的公钥
     ssh-keyscan -p "${REMOTE_PORT}" "${REMOTE_HOST}" >> ~/.ssh/known_hosts
     #通过sshpass配置免秘钥登录、并创建python3软连接
     sshpass -p "${REMOTE_PASS}" ssh-copy-id "${REMOTE_USER}@${REMOTE_HOST}"
     ssh ${REMOTE_HOST} ln -sv /usr/bin/python3 /usr/bin/python
     echo ${REMOTE_HOST} 免秘钥配置完成!
 done
 root@haproxy:~# bash key-scp.sh 

部署kubeasz

https://github.com/easzlab/kubeasz

 root@haproxy:~# apt install git
 root@haproxy:~# export release=3.6.5
 root@haproxy:~# wget https://github.com/easzlab/kubeasz/releases/download/${release}/ezdown
 root@haproxy:~# vim ezdown #可选⾃定义下载组件版本(按需修改可以使用默认配置)
 root@haproxy:~# chmod +x ezdown 
 root@haproxy:~# ./ezdown -D # 其实就是下载一些包为了加速可先用执行 docker pull easzlab/kubeasz:3.6.5(这里可能会报错但是不用担心,这一步的目的是下载一些docker镜像和二进制包,报错可以继续往下做)
 root@haproxy:~# ll /etc/kubeasz/
 total 140
 drwxrwxr-x  12 root root  4096 Dec 26 12:20 ./
 drwxr-xr-x 113 root root  4096 Dec 26 12:20 ../
 -rw-rw-r--   1 root root 20304 Nov 12 21:08 ansible.cfg
 drwxr-xr-x   5 root root  4096 Dec 26 12:20 bin/
 drwxrwxr-x   8 root root  4096 Nov 12 21:16 docs/
 drwxr-xr-x   3 root root  4096 Dec 26 12:36 down/
 drwxrwxr-x   2 root root  4096 Nov 12 21:16 example/
 -rwxrwxr-x   1 root root 26770 Nov 12 21:08 ezctl*
 -rwxrwxr-x   1 root root 32666 Nov 12 21:08 ezdown*
 drwxrwxr-x   4 root root  4096 Nov 12 21:16 .github/
 -rw-rw-r--   1 root root   301 Nov 12 21:08 .gitignore
 drwxrwxr-x  10 root root  4096 Nov 12 21:16 manifests/
 drwxrwxr-x   2 root root  4096 Nov 12 21:16 pics/
 drwxrwxr-x   2 root root  4096 Nov 12 21:16 playbooks/
 -rw-rw-r--   1 root root  6397 Nov 12 21:08 README.md
 drwxrwxr-x  22 root root  4096 Nov 12 21:16 roles/
 drwxrwxr-x   2 root root  4096 Nov 12 21:16 tools/
 ​
 ​
 root@haproxy:/etc/kubeasz#  vim clusters/k8s-cluster1/config.yml
 ...
 # [.]添加信任的私有仓库
 INSECURE_REG:
   - "http://easzlab.io.local:5000"
   - "http://harbor.stangj.com"
   - "https://reg.yourcompany.com"
 # [.]基础容器镜像
 SANDBOX_IMAGE: "harbor.stangj.com/baseimage/pause:3.10"
 ...
 ​
 ​

生成并⾃定义hosts⽂件

 `⽣产并⾃定义hosts⽂件`
 root@haproxy:~#  cd /etc/kubeasz/
 root@haproxy:/etc/kubeasz# docker tag easzlab/pause:3.10 harbor.stangj.com/baseimage/pause:3.10
 root@haproxy:/etc/kubeasz# docker push harbor.stangj.com/baseimage/pause:3.10
 root@haproxy:/etc/kubeasz# ./ezctl new k8s-cluster1
 root@haproxy:/etc/kubeasz# cat clusters/k8s-cluster1/hosts 
 # 'etcd' cluster should have odd member(s) (1,3,5,...)
 [etcd]
 192.168.139.121
 192.168.139.122
 192.168.139.123
 # master node(s), set unique 'k8s_nodename' for each node
 # CAUTION: 'k8s_nodename' must consist of lower case alphanumeric characters, '-' or '.',
 # and must start and end with an alphanumeric character
 [kube_master]
 192.168.139.121 k8s_nodename='master-01'
 192.168.139.122 k8s_nodename='master-02'
 #192.168.139.123 k8s_nodename='master-03'
 ​
 # work node(s), set unique 'k8s_nodename' for each node
 # CAUTION: 'k8s_nodename' must consist of lower case alphanumeric characters, '-' or '.',
 # and must start and end with an alphanumeric character
 [kube_node]
 192.168.139.124 k8s_nodename='node-01'
 #192.168.139.125 k8s_nodename='node-02'
 ​
 # [optional] harbor server, a private docker registry
 # 'NEW_INSTALL': 'true' to install a harbor server; 'false' to integrate with existed one
 [harbor]
 #192.168.1.8 NEW_INSTALL=false
 ​
 # [optional] loadbalance for accessing k8s from outside
 [ex_lb]
 #192.168.1.6 LB_ROLE=backup EX_APISERVER_VIP=192.168.1.250 EX_APISERVER_PORT=8443
 #192.168.139.36 LB_ROLE=master EX_APISERVER_VIP=192.168.139.248 EX_APISERVER_PORT=6443
 ​
 # [optional] ntp server for the cluster
 [chrony]
 #192.168.1.1
 ​
 [all:vars]
 # --------- Main Variables ---------------
 # Secure port for apiservers
 SECURE_PORT="6443"
 ​
 # Cluster container-runtime supported: docker, containerd
 # if k8s version >= 1.24, docker is not supported
 CONTAINER_RUNTIME="containerd"
 ​
 # Network plugins supported: calico, flannel, kube-router, cilium, kube-ovn
 CLUSTER_NETWORK="calico"
 ​
 # Service proxy mode of kube-proxy: 'iptables' or 'ipvs'
 PROXY_MODE="ipvs"
 ​
 # K8S Service CIDR, not overlap with node(host) networking
 SERVICE_CIDR="10.100.0.0/16"
 ​
 # Cluster CIDR (Pod CIDR), not overlap with node(host) networking
 CLUSTER_CIDR="10.200.0.0/16"
 ​
 # NodePort Range
 NODE_PORT_RANGE="30000-62767"
 ​
 # Cluster DNS Domain
 CLUSTER_DNS_DOMAIN="cluster.local"
 ​
 # -------- Additional Variables (don't change the default value right now) ---
 # Binaries Directory
 bin_dir="/usr/local/bin"    # 这个比较重要
 ​
 # Deploy Directory (kubeasz workspace)
 base_dir="/etc/kubeasz"
 ​
 # Directory for a specific cluster
 cluster_dir="{{ base_dir }}/clusters/k8s-cluster1"
 ​
 # CA and other components cert/key Directory
 ca_dir="/etc/kubernetes/ssl"
 ​
 # Default 'k8s_nodename' is empty
 k8s_nodename=''
 ​
 # Default python interpreter
 ansible_python_interpreter=/usr/bin/python3

编辑cluster config.yml⽂件

 root@haproxy:/etc/kubeasz# cat clusters/k8s-cluster1/config.yml 
 ############################
 # prepare
 ############################
 # 可选离线安装系统软件包 (offline|online)
 INSTALL_SOURCE: "online"
 ​
 # 可选进行系统安全加固 github.com/dev-sec/ansible-collection-hardening
 # (deprecated) 未更新上游项目,未验证最新k8s集群安装,不建议启用
 OS_HARDEN: false
 ​
 ​
 ############################
 # role:deploy
 ############################
 # default: ca will expire in 100 years
 # default: certs issued by the ca will expire in 50 years
 CA_EXPIRY: "876000h"
 CERT_EXPIRY: "438000h"
 ​
 # force to recreate CA and other certs, not suggested to set 'true'
 CHANGE_CA: false
 ​
 # kubeconfig 配置参数
 CLUSTER_NAME: "cluster1"
 CONTEXT_NAME: "context-{{ CLUSTER_NAME }}"
 ​
 # k8s version
 K8S_VER: "1.31.2"
 ​
 # set unique 'k8s_nodename' for each node, if not set(default:'') ip add will be used
 # CAUTION: 'k8s_nodename' must consist of lower case alphanumeric characters, '-' or '.',
 # and must start and end with an alphanumeric character (e.g. 'example.com'),
 # regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*'
 K8S_NODENAME: "{%- if k8s_nodename != '' -%} \
                     {{ k8s_nodename|replace('_', '-')|lower }} \
                {%- else -%} \
                     k8s-{{ inventory_hostname|replace('.', '-') }} \
                {%- endif -%}"
 ​
 # use 'K8S_NODENAME' to set hostname
 ENABLE_SETTING_HOSTNAME: true
 ​
 ​
 ############################
 # role:etcd
 ############################
 # 设置不同的wal目录,可以避免磁盘io竞争,提高性能
 ETCD_DATA_DIR: "/var/lib/etcd"
 ETCD_WAL_DIR: ""
 ​
 ​
 ############################
 # role:runtime [containerd,docker]
 ############################
 # [.]启用拉取加速镜像仓库
 ENABLE_MIRROR_REGISTRY: true
 ​
 # [.]添加信任的私有仓库
 # 必须按照如下示例格式,协议头'http://'和'https://'不能省略
 INSECURE_REG:
   - "http://easzlab.io.local:5000"
   - "http://harbor.stangj.com"
   - "https://reg.yourcompany.com"
 ​
 # [.]基础容器镜像
 SANDBOX_IMAGE: "harbor.stangj.com/baseimage/pause:3.10"
 ​
 # [containerd]容器持久化存储目录
 CONTAINERD_STORAGE_DIR: "/var/lib/containerd"
 ​
 # [docker]容器存储目录
 DOCKER_STORAGE_DIR: "/var/lib/docker"
 ​
 # [docker]开启Restful API
 DOCKER_ENABLE_REMOTE_API: false
 ​
 ​
 ############################
 # role:kube-master
 ############################
 # k8s 集群 master 节点证书配置,可以添加多个ip和域名(比如增加公网ip和域名)
 MASTER_CERT_HOSTS:
   - "192.168.139.248"
   - "k8s-api.stangj.io"
 ​
 # node 节点上 pod 网段掩码长度(决定每个节点最多能分配的pod ip地址)
 # 如果flannel 使用 --kube-subnet-mgr 参数,那么它将读取该设置为每个节点分配pod网段
 # https://github.com/coreos/flannel/issues/847
 NODE_CIDR_LEN: 24
 ​
 ​
 ############################
 # role:kube-node
 ############################
 # Kubelet 根目录
 KUBELET_ROOT_DIR: "/var/lib/kubelet"
 ​
 # node节点最大pod 数
 MAX_PODS: 200
 ​
 # 配置为kube组件(kubelet,kube-proxy,dockerd等)预留的资源量
 # 数值设置详见templates/kubelet-config.yaml.j2
 KUBE_RESERVED_ENABLED: "no"
 ​
 # k8s 官方不建议草率开启 system-reserved, 除非你基于长期监控,了解系统的资源占用状况;
 # 并且随着系统运行时间,需要适当增加资源预留,数值设置详见templates/kubelet-config.yaml.j2
 # 系统预留设置基于 4c/8g 虚机,最小化安装系统服务,如果使用高性能物理机可以适当增加预留
 # 另外,集群安装时候apiserver等资源占用会短时较大,建议至少预留1g内存
 SYS_RESERVED_ENABLED: "no"
 ​
 ​
 ############################
 # role:network [flannel,calico,cilium,kube-ovn,kube-router]
 ############################
 # ------------------------------------------- flannel
 # [flannel]设置flannel 后端"host-gw","vxlan"等
 FLANNEL_BACKEND: "vxlan"
 DIRECT_ROUTING: false
 ​
 # [flannel] 
 flannel_ver: "v0.26.0"
 ​
 # ------------------------------------------- calico
 # [calico] IPIP隧道模式可选项有: [Always, CrossSubnet, Never],跨子网可以配置为Always与CrossSubnet(公有云建议使用always比较省事,其他的话需要修改各自公有云的网络配置,具体可以参考各个公有云说明)
 # 其次CrossSubnet为隧道+BGP路由混合模式可以提升网络性能,同子网配置为Never即可.
 CALICO_IPV4POOL_IPIP: "Always"
 ​
 # [calico]设置 calico-node使用的host IP,bgp邻居通过该地址建立,可手工指定也可以自动发现
 IP_AUTODETECTION_METHOD: "can-reach={{ groups['kube_master'][0] }}"
 ​
 # [calico]设置calico 网络 backend: bird, vxlan, none
 CALICO_NETWORKING_BACKEND: "bird"
 ​
 # [calico]设置calico 是否使用route reflectors
 # 如果集群规模超过50个节点,建议启用该特性
 CALICO_RR_ENABLED: false
 ​
 # CALICO_RR_NODES 配置route reflectors的节点,如果未设置默认使用集群master节点 
 # CALICO_RR_NODES: ["192.168.1.1", "192.168.1.2"]
 CALICO_RR_NODES: []
 ​
 # [calico]更新支持calico 版本: ["3.19", "3.23"]
 calico_ver: "v3.28.2"
 ​
 # [calico]calico 主版本
 calico_ver_main: "{{ calico_ver.split('.')[0] }}.{{ calico_ver.split('.')[1] }}"
 ​
 # ------------------------------------------- cilium
 # [cilium]镜像版本
 cilium_ver: "1.16.3"
 cilium_connectivity_check: true
 cilium_hubble_enabled: false
 cilium_hubble_ui_enabled: false
 ​
 # ------------------------------------------- kube-ovn
 # [kube-ovn]离线镜像tar包
 kube_ovn_ver: "v1.11.5"
 ​
 # ------------------------------------------- kube-router
 # [kube-router]公有云上存在限制,一般需要始终开启 ipinip;自有环境可以设置为 "subnet"
 OVERLAY_TYPE: "full"
 ​
 # [kube-router]NetworkPolicy 支持开关
 FIREWALL_ENABLE: true
 ​
 # [kube-router]kube-router 镜像版本
 kube_router_ver: "v1.5.4"
 ​
 ​
 ############################
 # role:cluster-addon
 ############################
 # coredns 自动安装
 dns_install: "no"
 corednsVer: "1.11.3"
 ENABLE_LOCAL_DNS_CACHE: false
 dnsNodeCacheVer: "1.23.1"
 # 设置 local dns cache 地址
 LOCAL_DNS_CACHE: "169.254.20.10"
 ​
 # metric server 自动安装
 metricsserver_install: "no"
 metricsVer: "v0.7.2"
 ​
 # dashboard 自动安装
 dashboard_install: "no"
 dashboardVer: "v2.7.0"
 dashboardMetricsScraperVer: "v1.0.8"
 ​
 # prometheus 自动安装
 prom_install: "no"
 prom_namespace: "monitor"
 prom_chart_ver: "45.23.0"
 ​
 # kubeapps 自动安装,如果选择安装,默认同时安装local-storage(提供storageClass: "local-path")
 kubeapps_install: "no"
 kubeapps_install_namespace: "kubeapps"
 kubeapps_working_namespace: "default"
 kubeapps_storage_class: "local-path"
 kubeapps_chart_ver: "12.4.3"
 ​
 # local-storage (local-path-provisioner) 自动安装
 local_path_provisioner_install: "no"
 local_path_provisioner_ver: "v0.0.26"
 # 设置默认本地存储路径
 local_path_provisioner_dir: "/opt/local-path-provisioner"
 ​
 # nfs-provisioner 自动安装
 nfs_provisioner_install: "no"
 nfs_provisioner_namespace: "kube-system"
 nfs_provisioner_ver: "v4.0.2"
 nfs_storage_class: "managed-nfs-storage"
 nfs_server: "192.168.1.10"
 nfs_path: "/data/nfs"
 ​
 # network-check 自动安装
 network_check_enabled: false 
 network_check_schedule: "*/5 * * * *"
 ​
 ############################
 # role:harbor
 ############################
 # harbor version,完整版本号
 HARBOR_VER: "v2.11.1"
 HARBOR_DOMAIN: "harbor.easzlab.io.local"
 HARBOR_PATH: /var/data
 HARBOR_TLS_PORT: 8443
 HARBOR_REGISTRY: "{{ HARBOR_DOMAIN }}:{{ HARBOR_TLS_PORT }}"
 ​
 # if set 'false', you need to put certs named harbor.pem and harbor-key.pem in directory 'down'
 HARBOR_SELF_SIGNED_CERT: false
 # install extra component
 HARBOR_WITH_TRIVY: false

3.)ezctl 部署k8s集群

环境初始化

 root@haproxy:/etc/kubeasz# ./ezctl --help
 Usage: ezctl COMMAND [args]
 -------------------------------------------------------------------------------------
 Cluster setups:
     list                     to list all of the managed clusters
     checkout    <cluster>            to switch default kubeconfig of the cluster
     new         <cluster>            to start a new k8s deploy with name 'cluster'
     setup       <cluster>  <step>    to setup a cluster, also supporting a step-by-step way
     start       <cluster>            to start all of the k8s services stopped by 'ezctl stop'
     stop        <cluster>            to stop all of the k8s services temporarily
     upgrade     <cluster>            to upgrade the k8s cluster
     destroy     <cluster>            to destroy the k8s cluster
     backup      <cluster>            to backup the cluster state (etcd snapshot)
     restore     <cluster>            to restore the cluster state from backups
     start-aio                    to quickly setup an all-in-one cluster with default settings
 ​
 Cluster ops:
     add-etcd    <cluster>  <ip>      to add a etcd-node to the etcd cluster
     add-master  <cluster>  <ip>      to add a master node to the k8s cluster
     add-node    <cluster>  <ip>      to add a work node to the k8s cluster
     del-etcd    <cluster>  <ip>      to delete a etcd-node from the etcd cluster
     del-master  <cluster>  <ip>      to delete a master node from the k8s cluster
     del-node    <cluster>  <ip>      to delete a work node from the k8s cluster
 ​
 Extra operation:
     kca-renew   <cluster>            to force renew CA certs and all the other certs (with caution)
     kcfg-adm    <cluster>  <args>    to manage client kubeconfig of the k8s cluster
 ​
 Use "ezctl help <command>" for more information about a given command.
 ​
 root@haproxy:/etc/kubeasz#  ./ezctl setup k8s-cluster1 --help
 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@haproxy:/etc/kubeasz#  ./ezctl setup k8s-cluster1 01

部署etcd集群

 root@haproxy:/etc/kubeasz# ./ezctl setup k8s-cluster1 02 #部署etcd集群

验证集群

 root@master-01:~# export NODE_IPS="192.168.139.121 192.168.139.122 192.168.139.123"
 root@master-01:~# for ip in ${NODE_IPS}; do ETCDCTL_API=3 /usr/local/bin/etcdctl --endpoints=https://${ip}:2379 --cacert=/etc/kubernetes/ssl/ca.pem --cert=/etc/kubernetes/ssl/etcd.pem --key=/etc/kubernetes/ssl/etcd-key.pem endpoint health; done
 https://192.168.139.121:2379 is healthy: successfully committed proposal: took = 8.660445ms
 https://192.168.139.122:2379 is healthy: successfully committed proposal: took = 9.191232ms
 https://192.168.139.123:2379 is healthy: successfully committed proposal: took = 9.962348ms

部署容器运⾏时containerd

 root@haproxy:/etc/kubeasz# grep 'pause' ./clusters/k8s-cluster1/config.yml 
 SANDBOX_IMAGE: "harbor.stangj.com/baseimage/pause:3.10"
 `配置harbor镜像仓库域名解析-公司有DNS服务器进⾏域名解析`
 root@haproxy:/etc/kubeasz# vim roles/containerd/tasks/main.yml
 # 在 34,35行添加下面两行内容
     - name: 添加域名解析
       shell: "echo '192.168.139.100 harbor.stangj.com' >> /etc/hosts"
 ​
 ############################################################################################################
 ###############################下面内容不配置 nerdctl 可以不用执行#############################################
 `可选⾃定义containerd配置⽂件(可选)`
 root@k8s-deploy:/etc/kubeasz# vim roles/containerd/templates/config.toml.j2
 `配置nerdctl客户端方便使用(可选)nerdctl 工具可到github下载 https://github.com/containerd/nerdctl`
 root@haproxy:/usr/local/src# tar xf nerdctl-2.0.1-linux-amd64.tar.gz -C /etc/kubeasz/bin/containerd-bin/
 root@haproxy:/etc/kubeasz# vim roles/containerd/tasks/main.yml
 # 行 
   5 - block:
   6     - name: 准备containerd相关目录
   7       file: name={{ item }} state=directory
   8       with_items:
   9       - "{{ bin_dir }}/containerd-bin"
  10       - "/etc/containerd"
  11       - "/etc/nerdctl/"  # 配置文件目录
  16     - name: 下载 containerd 二进制文件
  17       copy: src={{ item }} dest={{ bin_dir }}/containerd-bin/ mode=0755
  18       with_fileglob:
  19       - "{{ base_dir }}/bin/containerd-bin/*"
  20       - nerdctl # 添加分发nerdctl
  21       tags: upgrade
  37     - name: 创建 nerdctl 配置文件
  38       template: src=nerdctl.toml.j2 dest=/etc/nerdctl/nerdctl.toml #分发nerdctl配置⽂件
  39       tags: upgrade
 `nerdctl配置⽂件`
 root@haproxy:/etc/kubeasz# vim roles/containerd/templates/nerdctl.toml.j2
 namespace = "k8s.io"
 debug = false
 debug_full = false
 insecure_registry = true

执行部署运行时

 root@haproxy:/etc/kubeasz# ./ezctl setup k8s-cluster1 03
 ​
 root@master-01:~# nerdctl -v
 nerdctl version 2.0.1

部署kubernetes master节点

 root@haproxy:/etc/kubeasz# vim roles/kube-master/tasks/main.yml # 可自定义配置
 root@haproxy:/etc/kubeasz# ./ezctl setup k8s-cluster1 04
 `将 config 拷贝到 master 节点`
 root@haproxy:/etc/kubeasz# export NODE_IPS="192.168.139.121 192.168.139.122 192.168.139.123"
 root@haproxy:/etc/kubeasz# for IP in $NODE_IPS ;do scp /root/.kube/config ${IP}:/root/.kube/ ;done
 ​
 root@master-01:~# kubectl get node
 NAME        STATUS                     ROLES    AGE    VERSION
 master-01   Ready,SchedulingDisabled   master   15m    v1.31.2
 master-02   Ready,SchedulingDisabled   master   15m    v1.31.2

部署kubernetes node节点

 root@haproxy:/etc/kubeasz# ./ezctl setup k8s-cluster1 05
 root@master-01:~# kubectl get node
 NAME        STATUS                     ROLES    AGE     VERSION
 master-01   Ready,SchedulingDisabled   master   15m     v1.31.2
 master-02   Ready,SchedulingDisabled   master   15m     v1.31.2
 node-01     Ready                      node     6m18s   v1.31.2

部署⽹络服务calico

更改calico的镜像地址及各种配置信息(可选)

 root@haproxy:/etc/kubeasz# vim ./clusters/k8s-cluster1/config.yml # 可自定义修改
 ....
 # [calico]更新支持calico 版本: ["3.19", "3.23"]
 calico_ver: "v3.28.2"
 .....
 `查看镜像`
 root@haproxy:/etc/kubeasz# grep "image:" roles/calico/templates/calico-v3.28.yaml.j2 
           image: easzlab.io.local:5000/calico/cni:{{ calico_ver }}
           image: easzlab.io.local:5000/calico/node:{{ calico_ver }} 
           image: easzlab.io.local:5000/calico/node:{{ calico_ver }}
           image: easzlab.io.local:5000/calico/kube-controllers:{{ calico_ver }}
 `修改镜像`
 root@haproxy:/etc/kubeasz# docker images | grep  calico | grep easzlab
 easzlab.io.local:5000/calico/kube-controllers             v3.28.2        b5eafd94250c   3 months ago    79MB
 easzlab.io.local:5000/calico/cni                          v3.28.2        8db78ebb3152   3 months ago    209MB
 easzlab.io.local:5000/calico/node                         v3.28.2        f3bc59d46b56   3 months ago    372MB
 root@haproxy:/etc/kubeasz# docker tag easzlab.io.local:5000/calico/kube-controllers:v3.28.2 harbor.stangj.com/baseimage/kube-controllers:v3.28.2
 root@haproxy:/etc/kubeasz# docker push harbor.stangj.com/baseimage/kube-controllers:v3.28.2
 root@haproxy:/etc/kubeasz# docker tag easzlab.io.local:5000/calico/cni:v3.28.2 harbor.stangj.com/baseimage/cni:v3.28.2
 root@haproxy:/etc/kubeasz# docker push harbor.stangj.com/baseimage/cni:v3.28.2
 root@haproxy:/etc/kubeasz# docker tag easzlab.io.local:5000/calico/node:v3.28.2 harbor.stangj.com/baseimage/node:v3.28.2
 root@haproxy:/etc/kubeasz# docker push harbor.stangj.com/baseimage/node:v3.28.2
 `修改yaml⽂件中的镜像地址`
 root@haproxy:/etc/kubeasz# vim roles/calico/templates/calico-v3.28.yaml.j2 
 root@haproxy:/etc/kubeasz# grep "image:" roles/calico/templates/calico-v3.28.yaml.j2 
           image: harbor.stangj.com/baseimage/cni:v3.28.2
           image: harbor.stangj.com/baseimage/node:v3.28.2
           image: harbor.stangj.com/baseimage/node:v3.28.2
           image: harbor.stangj.com/baseimage/kube-controllers:v3.28.2

部署calico

 root@haproxy:/etc/kubeasz# ./ezctl setup k8s-cluster1 06

验证calico

 root@master-01:~# calicoctl node status
 Calico process is running.
 ​
 IPv4 BGP status
 +-----------------+-------------------+-------+----------+-------------+
 |  PEER ADDRESS   |     PEER TYPE     | STATE |  SINCE   |    INFO     |
 +-----------------+-------------------+-------+----------+-------------+
 | 192.168.139.122 | node-to-node mesh | up    | 09:23:34 | Established |
 | 192.168.139.124 | node-to-node mesh | up    | 09:23:46 | Established |
 +-----------------+-------------------+-------+----------+-------------+

验证pod 通信

 root@master-01:~# kubectl run client-1 --image=harbor.stangj.com/baseimage/demoapp:v1.0
 root@master-01:~# kubectl run client-2 --image=harbor.stangj.com/baseimage/demoapp:v1.0
 root@master-01:~# kubectl get pod -o wide
 NAME       READY   STATUS    RESTARTS   AGE     IP             NODE      NOMINATED NODE   READINESS GATES
 client-1   1/1     Running   0          3m8s    10.200.190.6   node-01   <none>           <none>
 client-2   1/1     Running   0          2m59s   10.200.190.7   node-01   <none>           <none>
 root@master-01:~# kubectl exec -it client-1 -- sh
 [root@client-1 /]# ping 10.200.190.7 
 PING 10.200.190.7 (10.200.190.7): 56 data bytes
 64 bytes from 10.200.190.7: seq=0 ttl=63 time=0.198 ms

部署coredns

coredns1.11.3 的yaml文件

https://github.com/kubernetes/kubernetes/blob/release-1.31/cluster/addons/dns/coredns/coredns.yaml.base

coredns版本对照表

https://github.com/coredns/deployment/blob/master/kubernetes/CoreDNS-k8s_version.md

 root@haproxy:/etc/kubeasz# docker tag easzlab.io.local:5000/coredns/coredns:1.11.3 harbor.stangj.com/baseimage/coredns:1.11.3
 root@haproxy:/etc/kubeasz# docker push harbor.stangj.com/baseimage/coredns:1.11.3
 root@master-01:~# cat coredns-1.11.3.yaml 
 # __MACHINE_GENERATED_WARNING__
 ​
 apiVersion: v1
 kind: ServiceAccount
 metadata:
   name: coredns
   namespace: kube-system
   labels:
       kubernetes.io/cluster-service: "true"
       addonmanager.kubernetes.io/mode: Reconcile
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRole
 metadata:
   labels:
     kubernetes.io/bootstrapping: rbac-defaults
     addonmanager.kubernetes.io/mode: Reconcile
   name: system:coredns
 rules:
 - apiGroups:
   - ""
   resources:
   - endpoints
   - services
   - pods
   - namespaces
   verbs:
   - list
   - watch
 - apiGroups:
   - discovery.k8s.io
   resources:
   - endpointslices
   verbs:
   - list
   - watch
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
 metadata:
   annotations:
     rbac.authorization.kubernetes.io/autoupdate: "true"
   labels:
     kubernetes.io/bootstrapping: rbac-defaults
     addonmanager.kubernetes.io/mode: EnsureExists
   name: system:coredns
 roleRef:
   apiGroup: rbac.authorization.k8s.io
   kind: ClusterRole
   name: system:coredns
 subjects:
 - kind: ServiceAccount
   name: coredns
   namespace: kube-system
 ---
 apiVersion: v1
 kind: ConfigMap
 metadata:
   name: coredns
   namespace: kube-system
   labels:
       addonmanager.kubernetes.io/mode: EnsureExists
 data:
   Corefile: |
     .:53 {
         errors
         health {
             lameduck 5s
         }
         ready
         kubernetes cluster.local in-addr.arpa ip6.arpa {    # 修改点
             pods insecure
             fallthrough in-addr.arpa ip6.arpa
             ttl 30
         }
         prometheus :9153
         #forward . /etc/resolv.conf {
         forward . 223.6.6.6 {               # 修改点
             max_concurrent 1000
         }
         cache 600                           # 修改点
         loop
         reload
         loadbalance
     }
 ---
 apiVersion: apps/v1
 kind: Deployment
 metadata:
   name: coredns
   namespace: kube-system
   labels:
     k8s-app: kube-dns
     kubernetes.io/cluster-service: "true"
     addonmanager.kubernetes.io/mode: Reconcile
     kubernetes.io/name: "CoreDNS"
 spec:
   # replicas: not specified here:
   # 1. In order to make Addon Manager do not reconcile this replicas parameter.
   # 2. Default is 1.
   # 3. Will be tuned in real time if DNS horizontal auto-scaling is turned on.
   strategy:
     type: RollingUpdate
     rollingUpdate:
       maxUnavailable: 1
   selector:
     matchLabels:
       k8s-app: kube-dns
   template:
     metadata:
       labels:
         k8s-app: kube-dns
     spec:
       securityContext:
         seccompProfile:
           type: RuntimeDefault
       priorityClassName: system-cluster-critical
       serviceAccountName: coredns
       affinity:
         podAntiAffinity:
           preferredDuringSchedulingIgnoredDuringExecution:
           - weight: 100
             podAffinityTerm:
               labelSelector:
                 matchExpressions:
                   - key: k8s-app
                     operator: In
                     values: ["kube-dns"]
               topologyKey: kubernetes.io/hostname
       tolerations:
         - key: "CriticalAddonsOnly"
           operator: "Exists"
       nodeSelector:
         kubernetes.io/os: linux
       containers:
       - name: coredns
         image: harbor.stangj.com/baseimage/coredns:1.11.3
         imagePullPolicy: IfNotPresent
         resources:
           limits:      # 修改点
             memory: 256Mi 
             cpu: 200m
           requests:
             cpu: 100m
             memory: 70Mi
         args: [ "-conf", "/etc/coredns/Corefile" ]
         volumeMounts:
         - name: config-volume
           mountPath: /etc/coredns
           readOnly: true
         ports:
         - containerPort: 53
           name: dns
           protocol: UDP
         - containerPort: 53
           name: dns-tcp
           protocol: TCP
         - containerPort: 9153
           name: metrics
           protocol: TCP
         livenessProbe:
           httpGet:
             path: /health
             port: 8080
             scheme: HTTP
           initialDelaySeconds: 60
           timeoutSeconds: 5
           successThreshold: 1
           failureThreshold: 5
         readinessProbe:
           httpGet:
             path: /ready
             port: 8181
             scheme: HTTP
         securityContext:
           allowPrivilegeEscalation: false
           capabilities:
             add:
             - NET_BIND_SERVICE
             drop:
             - ALL
           readOnlyRootFilesystem: true
       dnsPolicy: Default
       volumes:
         - name: config-volume
           configMap:
             name: coredns
             items:
             - key: Corefile
               path: Corefile
 ---
 apiVersion: v1
 kind: Service
 metadata:
   name: kube-dns
   namespace: kube-system
   annotations:
     prometheus.io/port: "9153"
     prometheus.io/scrape: "true"
   labels:
     k8s-app: kube-dns
     kubernetes.io/cluster-service: "true"
     addonmanager.kubernetes.io/mode: Reconcile
     kubernetes.io/name: "CoreDNS"
 spec:
   selector:
     k8s-app: kube-dns
   clusterIP: 10.100.0.2 # /etc/kubeasz# grep 'SERVICE_CIDR' clusters/k8s-cluster1/hosts  集群service IP # 修改点 
   ports:                # SERVICE_CIDR="10.100.0.0/16"
   - name: dns
     port: 53
     protocol: UDP
   - name: dns-tcp
     port: 53
     protocol: TCP
   - name: metrics
     port: 9153
     protocol: TCP

验证服务

 root@master-01:~# kubectl get po -A
 NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE
 default       client-1                                   1/1     Running   0          52m
 default       client-2                                   1/1     Running   0          52m
 kube-system   calico-kube-controllers-7c54ddc76b-x9wbl   1/1     Running   0          65m
 kube-system   calico-node-g2t8r                          1/1     Running   0          65m
 kube-system   calico-node-n879l                          1/1     Running   0          65m
 kube-system   calico-node-tvj9q                          1/1     Running   0          65m
 kube-system   coredns-5c6d57bd94-k59j5                   1/1     Running   0          4m34s

验证pod内的域名通信

 root@master-01:~# kubectl create deployment demoapp --image=harbor.stangj.com/baseimage/demoapp:v1.0 --replicas=1
 root@master-01:~# kubectl create service nodeport demoapp --tcp=80:80
 root@master-01:~# kubectl run client-$RANDOM --image=registry.cn-zhangjiakou.aliyuncs.com/tanghao429/tanghao:admin-box.v-1.2 -it --command -- /bin/sh
 root@client-10711 # ping www.baidu.com
 PING www.baidu.com (110.242.68.4): 56 data bytes
 64 bytes from 110.242.68.4: seq=0 ttl=127 time=12.037 ms
 64 bytes from 110.242.68.4: seq=1 ttl=127 time=11.329 ms
 root@client-10711 # while true; do curl demoapp.default.svc; sleep 1; done
 iKubernetes demoapp v1.0 !! ClientIP: 10.200.190.15, ServerName: demoapp-69f7596784-km8wl, ServerIP: 10.200.190.14!
 iKubernetes demoapp v1.0 !! ClientIP: 10.200.190.15, ServerName: demoapp-69f7596784-km8wl, ServerIP: 10.200.190.14!
 iKubernetes demoapp v1.0 !! ClientIP: 10.200.190.15, ServerName: demoapp-69f7596784-km8wl, ServerIP: 10.200.190.14!

到此 K8S 集群已经搭建好了

4.)ezctl 附加功能

添加一个master节点

 root@haproxy:/etc/kubeasz# ./ezctl add-master --help
 root@haproxy:/etc/kubeasz# ./ezctl add-master k8s-cluster1 192.168.139.123
 root@haproxy:/etc/kubeasz# kubectl get node
 NAME                  STATUS                     ROLES    AGE    VERSION
 k8s-192-168-139-123   Ready,SchedulingDisabled   master   90s    v1.31.2
 master-01             Ready,SchedulingDisabled   master   131m   v1.31.2
 master-02             Ready,SchedulingDisabled   master   131m   v1.31.2
 node-01               Ready                      node     122m   v1.31.2

删除一个master节点

 root@haproxy:/etc/kubeasz# ./ezctl del-master k8s-cluster1 192.168.139.123
 root@master-01:~# kubectl get node
 NAME        STATUS                     ROLES    AGE    VERSION
 master-01   Ready,SchedulingDisabled   master   134m   v1.31.2
 master-02   Ready,SchedulingDisabled   master   134m   v1.31.2
 node-01     Ready                      node     125m   v1.31.2

添加一个node节点

 root@haproxy:/etc/kubeasz# ./ezctl add-node k8s-cluster1 192.168.139.125
 root@master-01:~# kubectl get node
 NAME                  STATUS                     ROLES    AGE     VERSION
 k8s-192-168-139-125   Ready                      node     2m23s   v1.31.2
 master-01             Ready,SchedulingDisabled   master   4h28m   v1.31.2
 master-02             Ready,SchedulingDisabled   master   4h28m   v1.31.2
 node-01               Ready                      node     4h18m   v1.31.2
 ​

验证服务

 root@master-01:~# kubectl create deployment demoapp --image=harbor.stangj.com/baseimage/demoapp:v1.0 --replicas=2
 root@master-01:~# kubectl create service nodeport demoapp --tcp=80:80
 root@master-01:~# kubectl get pod -o wide
 NAME                       READY   STATUS    RESTARTS       AGE    IP              NODE                  NOMINATED NODE   READINESS GATES
 client-10711               1/1     Running   1 (154m ago)   161m   10.200.190.11   node-01               <none>           <none>
 demoapp-69f7596784-xrtzx   1/1     Running   0              100s   10.200.190.16   node-01               <none>           <none>
 demoapp-69f7596784-xzpwf   1/1     Running   0              100s   10.200.208.65   k8s-192-168-139-125   <none>           <none>
 root@master-01:~# kubectl run client-$RANDOM --image=registry.cn-zhangjiakou.aliyuncs.com/tanghao429/tanghao:admin-box.v-1.2 -it --command -- /bin/sh
 root@client-19584 # while true; do curl demoapp.default.svc; sleep 1; done
 iKubernetes demoapp v1.0 !! ClientIP: 10.200.208.66, ServerName: demoapp-69f7596784-xzpwf, ServerIP: 10.200.208.65!
 iKubernetes demoapp v1.0 !! ClientIP: 10.200.208.66, ServerName: demoapp-69f7596784-xrtzx, ServerIP: 10.200.190.16!
 iKubernetes demoapp v1.0 !! ClientIP: 10.200.208.66, ServerName: demoapp-69f7596784-xzpwf, ServerIP: 10.200.208.65!
 root@client-19584 # ping jd.com
 PING jd.com (211.144.24.218): 56 data bytes
 64 bytes from 211.144.24.218: seq=0 ttl=127 time=5.443 ms

删除一个node节点

 root@haproxy:/etc/kubeasz# ./ezctl del-node k8s-cluster1 192.168.139.124
 root@master-01:~# kubectl get node
 NAME                  STATUS                     ROLES    AGE     VERSION
 k8s-192-168-139-123   Ready,SchedulingDisabled   master   7m37s   v1.31.2
 k8s-192-168-139-125   Ready                      node     34m     v1.31.2
 master-01             Ready,SchedulingDisabled   master   5h      v1.31.2
 master-02             Ready,SchedulingDisabled   master   5h      v1.31.2

5.)部署附件

部署 dashboard

镜像准备

 `上传镜像`
 root@haproxy:/etc/kubeasz# docker images | grep dashboard
 kubernetesui/dashboard                                    v2.7.0         07655ddf2eeb   2 years ago     246MB
 easzlab.io.local:5000/kubernetesui/dashboard              v2.7.0         07655ddf2eeb   2 years ago     246MB
 root@haproxy:/etc/kubeasz# docker tag kubernetesui/dashboard:v2.7.0  harbor.stangj.com/baseimage/dashboard:v2.7.0
 root@haproxy:/etc/kubeasz# docker push harbor.stangj.com/baseimage/dashboard:v2.7.0
 root@haproxy:/etc/kubeasz# docker tag kubernetesui/metrics-scraper:v1.0.8 harbor.stangj.com/baseimage/metrics-scraper:v1.0.8
 root@haproxy:/etc/kubeasz# docker push harbor.stangj.com/baseimage/metrics-scraper:v1.0.8

资源文件准备

 `编写资源yaml文件`
 root@master-01:~# cat admin-secret.yaml 
 apiVersion: v1
 kind: Secret
 type: kubernetes.io/service-account-token
 metadata:
   name: dashboard-admin-user
   namespace: kubernetes-dashboard 
   annotations:
     kubernetes.io/service-account.name: "admin-user"
 ​
 root@master-01:~# cat admin-user.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
   
   root@master-01:~# cat dashboard-v2.7.0.yaml 
 # Copyright 2017 The Kubernetes Authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
 #
 #     http://www.apache.org/licenses/LICENSE-2.0
 #
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
 ​
 apiVersion: v1
 kind: Namespace
 metadata:
   name: kubernetes-dashboard
 ​
 ---
 ​
 apiVersion: v1
 kind: ServiceAccount
 metadata:
   labels:
     k8s-app: kubernetes-dashboard
   name: kubernetes-dashboard
   namespace: kubernetes-dashboard
 ​
 ---
 ​
 kind: Service
 apiVersion: v1
 metadata:
   labels:
     k8s-app: kubernetes-dashboard
   name: kubernetes-dashboard
   namespace: kubernetes-dashboard
 spec:
   type: NodePort
   ports:
     - port: 443
       targetPort: 8443
       nodePort: 30000
   selector:
     k8s-app: kubernetes-dashboard
 ​
 ---
 ​
 apiVersion: v1
 kind: Secret
 metadata:
   labels:
     k8s-app: kubernetes-dashboard
   name: kubernetes-dashboard-certs
   namespace: kubernetes-dashboard
 type: Opaque
 ​
 ---
 ​
 apiVersion: v1
 kind: Secret
 metadata:
   labels:
     k8s-app: kubernetes-dashboard
   name: kubernetes-dashboard-csrf
   namespace: kubernetes-dashboard
 type: Opaque
 data:
   csrf: ""
 ​
 ---
 ​
 apiVersion: v1
 kind: Secret
 metadata:
   labels:
     k8s-app: kubernetes-dashboard
   name: kubernetes-dashboard-key-holder
   namespace: kubernetes-dashboard
 type: Opaque
 ​
 ---
 ​
 kind: ConfigMap
 apiVersion: v1
 metadata:
   labels:
     k8s-app: kubernetes-dashboard
   name: kubernetes-dashboard-settings
   namespace: kubernetes-dashboard
 ​
 ---
 ​
 kind: Role
 apiVersion: rbac.authorization.k8s.io/v1
 metadata:
   labels:
     k8s-app: kubernetes-dashboard
   name: kubernetes-dashboard
   namespace: kubernetes-dashboard
 rules:
   # Allow Dashboard to get, update and delete Dashboard exclusive secrets.
   - apiGroups: [""]
     resources: ["secrets"]
     resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"]
     verbs: ["get", "update", "delete"]
     # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
   - apiGroups: [""]
     resources: ["configmaps"]
     resourceNames: ["kubernetes-dashboard-settings"]
     verbs: ["get", "update"]
     # Allow Dashboard to get metrics.
   - apiGroups: [""]
     resources: ["services"]
     resourceNames: ["heapster", "dashboard-metrics-scraper"]
     verbs: ["proxy"]
   - apiGroups: [""]
     resources: ["services/proxy"]
     resourceNames: ["heapster", "http:heapster:", "https:heapster:", "dashboard-metrics-scraper", "http:dashboard-metrics-scraper"]
     verbs: ["get"]
 ​
 ---
 ​
 kind: ClusterRole
 apiVersion: rbac.authorization.k8s.io/v1
 metadata:
   labels:
     k8s-app: kubernetes-dashboard
   name: kubernetes-dashboard
 rules:
   # Allow Metrics Scraper to get metrics from the Metrics server
   - apiGroups: ["metrics.k8s.io"]
     resources: ["pods", "nodes"]
     verbs: ["get", "list", "watch"]
 ​
 ---
 ​
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
 metadata:
   labels:
     k8s-app: kubernetes-dashboard
   name: kubernetes-dashboard
   namespace: kubernetes-dashboard
 roleRef:
   apiGroup: rbac.authorization.k8s.io
   kind: Role
   name: kubernetes-dashboard
 subjects:
   - kind: ServiceAccount
     name: kubernetes-dashboard
     namespace: kubernetes-dashboard
 ​
 ---
 ​
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
 metadata:
   name: kubernetes-dashboard
 roleRef:
   apiGroup: rbac.authorization.k8s.io
   kind: ClusterRole
   name: kubernetes-dashboard
 subjects:
   - kind: ServiceAccount
     name: kubernetes-dashboard
     namespace: kubernetes-dashboard
 ​
 ---
 ​
 kind: Deployment
 apiVersion: apps/v1
 metadata:
   labels:
     k8s-app: kubernetes-dashboard
   name: kubernetes-dashboard
   namespace: kubernetes-dashboard
 spec:
   replicas: 1
   revisionHistoryLimit: 10
   selector:
     matchLabels:
       k8s-app: kubernetes-dashboard
   template:
     metadata:
       labels:
         k8s-app: kubernetes-dashboard
     spec:
       securityContext:
         seccompProfile:
           type: RuntimeDefault
       containers:
         - name: kubernetes-dashboard
           image: harbor.stangj.com/baseimage/dashboard:v2.7.0
           imagePullPolicy: Always
           ports:
             - containerPort: 8443
               protocol: TCP
           args:
             - --auto-generate-certificates
             - --namespace=kubernetes-dashboard
             - --token-ttl=3600
             # Uncomment the following line to manually specify Kubernetes API server Host
             # If not specified, Dashboard will attempt to auto discover the API server and connect
             # to it. Uncomment only if the default does not work.
             # - --apiserver-host=http://my-address:port
           volumeMounts:
             - name: kubernetes-dashboard-certs
               mountPath: /certs
               # Create on-disk volume to store exec logs
             - mountPath: /tmp
               name: tmp-volume
           livenessProbe:
             httpGet:
               scheme: HTTPS
               path: /
               port: 8443
             initialDelaySeconds: 30
             timeoutSeconds: 30
           securityContext:
             allowPrivilegeEscalation: false
             readOnlyRootFilesystem: true
             runAsUser: 1001
             runAsGroup: 2001
       volumes:
         - name: kubernetes-dashboard-certs
           secret:
             secretName: kubernetes-dashboard-certs
         - name: tmp-volume
           emptyDir: {}
       serviceAccountName: kubernetes-dashboard
       nodeSelector:
         "kubernetes.io/os": linux
       # Comment the following tolerations if Dashboard must not be deployed on master
       tolerations:
         - key: node-role.kubernetes.io/master
           effect: NoSchedule
 ​
 ---
 ​
 kind: Service
 apiVersion: v1
 metadata:
   labels:
     k8s-app: dashboard-metrics-scraper
   name: dashboard-metrics-scraper
   namespace: kubernetes-dashboard
 spec:
   ports:
     - port: 8000
       targetPort: 8000
   selector:
     k8s-app: dashboard-metrics-scraper
 ​
 ---
 ​
 kind: Deployment
 apiVersion: apps/v1
 metadata:
   labels:
     k8s-app: dashboard-metrics-scraper
   name: dashboard-metrics-scraper
   namespace: kubernetes-dashboard
 spec:
   replicas: 1
   revisionHistoryLimit: 10
   selector:
     matchLabels:
       k8s-app: dashboard-metrics-scraper
   template:
     metadata:
       labels:
         k8s-app: dashboard-metrics-scraper
     spec:
       securityContext:
         seccompProfile:
           type: RuntimeDefault
       containers:
         - name: dashboard-metrics-scraper
           image: harbor.stangj.com/baseimage/metrics-scraper:v1.0.8
           ports:
             - containerPort: 8000
               protocol: TCP
           livenessProbe:
             httpGet:
               scheme: HTTP
               path: /
               port: 8000
             initialDelaySeconds: 30
             timeoutSeconds: 30
           volumeMounts:
           - mountPath: /tmp
             name: tmp-volume
           securityContext:
             allowPrivilegeEscalation: false
             readOnlyRootFilesystem: true
             runAsUser: 1001
             runAsGroup: 2001
       serviceAccountName: kubernetes-dashboard
       nodeSelector:
         "kubernetes.io/os": linux
       # Comment the following tolerations if Dashboard must not be deployed on master
       tolerations:
         - key: node-role.kubernetes.io/master
           effect: NoSchedule
       volumes:
         - name: tmp-volume
           emptyDir: {}

部署服务

 root@master-01:~# kubectl create ns kubernetes-dashboard
 root@master-01:~# kubectl apply -f admin-user.yaml 
 root@master-01:~# kubectl apply -f admin-secret.yaml
 root@master-01:~# kubectl apply -f dashboard-v2.7.0.yaml 
 root@master-01:~# kubectl get pod -n kubernetes-dashboard
 NAME                                         READY   STATUS    RESTARTS   AGE
 dashboard-metrics-scraper-5b49cb7f4c-cggml   1/1     Running   0          26s
 kubernetes-dashboard-56bc75885-ckzd8         1/1     Running   0          26s

获取token并登录dashboard

 root@master-01:~# kubectl get secret -A | grep admin
 kubernetes-dashboard   dashboard-admin-user              kubernetes.io/service-account-token   3      103s
 root@master-01:~# kubectl -n kubernetes-dashboard describe secret dashboard-admin-user
 Name:         dashboard-admin-user
 Namespace:    kubernetes-dashboard
 Labels:       <none>
 Annotations:  kubernetes.io/service-account.name: admin-user
               kubernetes.io/service-account.uid: 55fa17b0-edcf-4244-906a-1a10ce2a7fbb
 ​
 Type:  kubernetes.io/service-account-token
 ​
 Data
 ====
 namespace:  20 bytes
 token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IkFKY3UzQXlJem9Sdm1tZ3dyZHNMcnRRZkNSS2ctTWU5ZGUtdHhTWEU1VEUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdXNlciIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJhZG1pbi11c2VyIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiNTVmYTE3YjAtZWRjZi00MjQ0LTkwNmEtMWExMGNlMmE3ZmJiIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmVybmV0ZXMtZGFzaGJvYXJkOmFkbWluLXVzZXIifQ.BoHEbTatvvH95je_7MBexzGsQBqlNLZ4SzSOWX1bgOg-0A4WGHWDvo-cx16Q2nJ7IiM3G-DWg0ZtbF_4ITfv-ra-V9YUYwA3mZ8HxRZ9SAqpEgfmk3kTXlugFV09a4sYrFhvCd24RregT1IK1zU3CfjRfpSzeFZ6RkpwHJX4Xy-rFK_Wgft_b-LYb-EEALP7xgKetu6vVvWMCEHOI6_f592_yQvcxVj55Tpt6z7jCEzpZQI3gTOAA5-2rp2B0qYDXp-qGw3kzT8YoUZvoQUTUDsmFpq1emK6Bq0WUeI3SOmmGe59ZKjjwztImGR3fAW_8lP-4z69rNKx4i63xXftPg
 ca.crt:     1310 bytes
 root@master-01:~# kubectl get svc -n kubernetes-dashboard
 NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)         AGE
 dashboard-metrics-scraper   ClusterIP   10.100.208.50    <none>        8000/TCP        2m34s
 kubernetes-dashboard        NodePort    10.100.254.152   <none>        443:30000/TCP   2m35s

设置token登录会话保持时间

 root@master-01:~# vim dashboard-v2.7.0.yaml 
 ...........
     spec:
       securityContext:
         seccompProfile:
           type: RuntimeDefault
       containers:
         - name: kubernetes-dashboard
           image: harbor.stangj.com/baseimage/dashboard:v2.7.0
           imagePullPolicy: Always
           ports:
             - containerPort: 8443
               protocol: TCP
           args:
             - --auto-generate-certificates
             - --namespace=kubernetes-dashboard
             - --token-ttl=3600   # 可以通过这个参数修改会话保持时间

部署 metrics-server

镜像准备

 root@haproxy:/etc/kubeasz# docker images | grep metrics-server
 easzlab/metrics-server                                    v0.7.2         83375c676b80   4 months ago    67.1MB
 easzlab.io.local:5000/easzlab/metrics-server              v0.7.2         83375c676b80   4 months ago    67.1MB
 root@haproxy:/etc/kubeasz# docker tag easzlab/metrics-server:v0.7.2 harbor.stangj.com/baseimage/metrics-server:v0.7.2
 root@haproxy:/etc/kubeasz# docker push harbor.stangj.com/baseimage/metrics-server:v0.7.2
 ​

部署服务

 root@master-01:~# wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.7.2/components.yaml
 root@master-01:~# mv components.yaml  metrics-server.yaml 
 root@master-01:~# vim metrics-server.yaml 
 ....
     spec:
       containers:
       - args:
         - --cert-dir=/tmp
         - --secure-port=10250
         - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
         - --kubelet-use-node-status-port
         - --metric-resolution=15s
         - --kubelet-insecure-tls  # 添加这一行
         image: harbor.stangj.com/baseimage/metrics-server:v0.7.2  # 修改镜像地址
         imagePullPolicy: IfNotPresent
 ....
 ​
 root@master-01:~# kubectl apply -f metrics-server.yaml 
 root@master-01:~# kubectl get pod -n kube-system
 NAME                                       READY   STATUS    RESTARTS   AGE
 calico-kube-controllers-7c54ddc76b-m58k6   1/1     Running   0          49m
 calico-node-4wzxw                          1/1     Running   0          41m
 calico-node-8vb5t                          1/1     Running   0          41m
 calico-node-hdcmh                          1/1     Running   0          42m
 calico-node-q2plr                          1/1     Running   0          41m
 coredns-5c6d57bd94-dbbfj                   1/1     Running   0          49m
 metrics-server-59c9f779c9-dbj2f            1/1     Running   0          47s

验证服务

 root@master-01:~# kubectl top node
 NAME                  CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%   
 k8s-192-168-139-123   52m          2%     1143Mi          43%       
 k8s-192-168-139-125   47m          2%     1436Mi          54%       
 master-01             71m          3%     2251Mi          62%       
 master-02             81m          4%     1720Mi          65% 
Archive Calendar
周一 周二 周三 周四 周五 周六 周日
 1
2345678
9101112131415
16171819202122
23242526272829
30  

COPYRIGHT © 2025 TH小破站. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

渝ICP备2023013789号

渝公网安备50011702500926号