1、二进制安装

一、服务器准备

1.1、服务器以及操作系统信息
hostnameIPOSrole
k8s-master-01192.168.222.151CentOS Linux release 7.9.2009master
k8s-master-02192.168.222.152CentOS Linux release 7.9.2009master
k8s-master-03192.168.222.153CentOS Linux release 7.9.2009master
k8s-node-01192.168.222.154CentOS Linux release 7.9.2009node
k8s-node-02192.168.222.155CentOS Linux release 7.9.2009node
1.2、部署规划

K8s 主机网络:192.168.222.0/24

K8s service 网络:10.96.0.0/16

K8s pod 网络:10.244.0.0/12

HA VIP: 192.168.222.150

1.2、yum源修改
# 添加阿里云yum源
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
yum install -y yum-utils device-mapper-persistent-data lvm2
​
# 添加阿里云docker源
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo

复制

1.3、基础软件安装
yum -y install wget jq psmisc vim net-tools telnet git bash-completion
​
# 证书生成工具,master-01安装即可
# 证书生成工具打包提供
wget "https://pkg.cfssl.org/R1.2/cfssl_linux-amd64" -O /usr/local/bin/cfssl
wget "https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64" -O /usr/local/bin/cfssljson
chmod +x /usr/local/bin/cfssl /usr/local/bin/cfssljson

复制

1.4、hosts文件配置,所有节点
# 修改hosts文件,增加一下内容
vim /etc/hosts
​
192.168.222.150 k8s-master-vip
192.168.222.151 k8s-master-01
192.168.222.152 k8s-master-02
192.168.222.153 k8s-master-03
192.168.222.154 k8s-node-01
192.168.222.155 k8s-node-02

复制

1.5系统设置,所有节点
# 关闭firewalld
systemctl disable --now firewalld
# 关闭dnsmasq
systemctl disable --now dnsmasq
# 关闭NetworkManager
systemctl disable --now NetworkManager
​
关闭selinux
setenforce 0
sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/sysconfig/selinux
sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selinux/config
​
# 关闭swap分区
swapoff -a && sysctl -w vm.swappiness=0
sed -ri '/^[^#]*swap/s@^@#@' /etc/fstab
​
# 时区设置
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
echo 'Asia/Shanghai' >/etc/timezone
​
# 时间同步
# 安装ntp
rpm -ivh http://mirrors.wlnmp.com/centos/wlnmp-release-centos.noarch.rpm
yum install ntpdate -y
# 设置时间同步
ntpdate time2.aliyun.com
# 加入到定时任务
crontab -e
# 内存如下
*/5 * * * * /usr/sbin/ntpdate time2.aliyun.com

复制

1.6、系统limit设置,所有节点
vim /etc/security/limits.conf
# 末尾添加如下内容
* soft nofile 65536
* hard nofile 131072
* soft nproc 65535
* hard nproc 655350
* soft memlock unlimited
* hard memlock unlimited 

复制

1.7、在master-01配置免密登录到其他服务器
# 生成证书
ssh-keygen -t rsa
​
# 配置免密登录
for i in k8s-master-01 k8s-master-02 k8s-master-03 k8s-node-01 k8s-node-02;do ssh-copy-id -i .ssh/id_rsa.pub $i;done

复制

二、升级系统以及内核 所有节点

# 将系统升级至最新,暂不升级内核,后续单独升级
yum update -y --exclude=kernel* && reboot

复制

2.2、升级内核,建议4.18以上

一定要升级内核,早期的内核会导致一些奇怪的问题,尤其是pod数量较多的时候

可以在https://www.kernel.org/ 查看内核版本信息

可以在http://193.49.22.109/elrepo/kernel/el7/x86_64/RPMS/ 找到各版本kernel安装包

需要注意的是不要盲目升级到最新版本,系统有可能会无法启动(老旧服务器)

# 下载选好的内核版本
wget http://193.49.22.109/elrepo/kernel/el7/x86_64/RPMS/kernel-ml-devel-4.19.12-1.el7.elrepo.x86_64.rpm
wget http://193.49.22.109/elrepo/kernel/el7/x86_64/RPMS/kernel-ml-4.19.12-1.el7.elrepo.x86_64.rpm
​
# 安装
yum localinstall -y kernel-ml*
​
# 更改启动内核
grub2-set-default  0 && grub2-mkconfig -o /etc/grub2.cfg
grubby --args="user_namespace.enable=1" --update-kernel="$(grubby --default-kernel)"
​
# 查看启动内核是否是我们需要的
grubby --default-kernel
​
# 重启生效,确认使用内核版本
reboot
uname -a

复制

2.3、内核参数
# 编辑配置/etc/sysctl.d/k8s.conf
cat > /etc/sysctl.d/k8s.conf <<EOF
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
fs.may_detach_mounts = 1
vm.overcommit_memory=1
net.ipv4.conf.all.route_localnet = 1
vm.panic_on_oom=0
fs.inotify.max_user_watches=89100
fs.file-max=52706963
fs.nr_open=52706963
net.netfilter.nf_conntrack_max=2310720
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl =15
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_orphans = 327680
net.ipv4.tcp_orphan_retries = 3
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.ip_conntrack_max = 65536
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_timestamps = 0
net.core.somaxconn = 16384
EOF
​
# 加载配置
sysctl --system

三、ipvs

默认使用iptables,在pod较多的时候网络转发慢,建议使用ipvs

3.1、安装ipvs
yum install ipvsadm ipset sysstat conntrack libseccomp -y

复制

3.2、配置ipvs模块
# 编辑配置信息
cat > /etc/modules-load.d/ipvs.conf <<EOF
ip_vs
ip_vs_lc
ip_vs_wlc
ip_vs_rr
ip_vs_wrr
ip_vs_lblc
ip_vs_lblcr
ip_vs_dh
ip_vs_sh
ip_vs_fo
ip_vs_nq
ip_vs_sed
ip_vs_ftp
ip_vs_sh
nf_conntrack
ip_tables
ip_set
xt_set
ipt_set
ipt_rpfilter
ipt_REJECT
ipip
EOF
​
# 重新加载
systemctl enable --now systemd-modules-load.service
​
# 重启
reboot
​
# 确认
lsmod | grep -e ip_vs -e nf_conntrack

四、基础应用安装

4.1、docker安装,所有节点

建议选择19版本最后一个小版本,20版本比较新可能出现一些未知问题,同时在1.23版本k8s将会放弃docker作为k8s的容器运行时

# 查看版本
yum list docker-ce --showduplicates | sort -r
​
# 安装19.03.9-3.el7
yum -y install docker-ce-19.03.9-3.el7 docker-ce-cli-19.03.9-3.el7
​
# 新版kubelet建议使用systemd,所以可以把docker的CgroupDriver改成systemd
# 日志设置
# 上传下载设置
# 镜像仓库设置
mkdir /etc/docker
cat > /etc/docker/daemon.json <<EOF
{  "registry-mirrors": [
    "https://registry.docker-cn.com",
    "http://hub-mirror.c.163.com",
    "https://docker.mirrors.ustc.edu.cn"
  ],
  "exec-opts": ["native.cgroupdriver=systemd"],
  "max-concurrent-downloads": 10,  "max-concurrent-uploads": 5,  "log-opts": {    "max-size": "300m",    "max-file": "2"  },
  "live-restore": true
}
EOF

# 重新加载配置,并启动
systemctl daemon-reload && systemctl enable --now docker
​
# 查看docker信息
docker info
4.2 Etcd安装,所有maste节点

查看要安装k8s的版本changelog,其中会有对应的etcd的版本

# 下载安装包,三个master
wget https://github.com/etcd-io/etcd/releases/download/v3.5.0/etcd-v3.5.0-linux-amd64.tar.gz
​
# 解压安装,三个master
tar -zxvf etcd-v3.5.0-linux-amd64.tar.gz --strip-components=1 -C /usr/local/bin etcd-v3.5.0-linux-amd64/etcd{,ctl}
​
# etcd证书签发,k8s-master-01签发,之后复制到其他节点
# 所有master节点创建etcd证书目录
mkdir /etc/etcd/ssl -p
​
# 生成ca证书csr
cat > etcd-ca-csr.json << EOF
{
  "CN": "etcd",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Hebei",
      "L": "Qinghuangdao",
      "O": "etcd",
      "OU": "Etcd Security"
    }
  ],
  "ca": {
    "expiry": "876000h"
  }
}
EOF
​
# 生成ca证书和ca证书的key
cfssl gencert -initca etcd-ca-csr.json | cfssljson -bare /etc/etcd/ssl/etcd-ca
​
# 使用ca证书签发客户端证书
# 生成etcd csr文件
cat > etcd-csr.json << EOF
{
  "CN": "etcd",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Hebei",
      "L": "Qinghuangdao",
      "O": "etcd",
      "OU": "Etcd Security"
    }
  ]
}
EOF
​
# 生成ca config
cat > ca-config.json << EOF
{
  "signing": {
    "default": {
      "expiry": "876000h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "876000h"
      }
    }
  }
}
EOF
​
# 生成etcd证书和key
# 替换主机名称和IP
cfssl gencert\
   -ca=/etc/etcd/ssl/etcd-ca.pem\
   -ca-key=/etc/etcd/ssl/etcd-ca-key.pem\
   -config=ca-config.json\
   -hostname=127.0.0.1,k8s-master-01,k8s-master-02,k8s-master-03,192.168.222.151,192.168.222.152,192.168.222.153\
   -profile=kubernetes\
   etcd-csr.json | cfssljson -bare /etc/etcd/ssl/etcd
​
# 复制证书到其他master节点
for NODE in k8s-master-02 k8s-master-03; do
     ssh $NODE "mkdir -p /etc/etcd/ssl"
     for FILE in etcd-ca-key.pem  etcd-ca.pem  etcd-key.pem  etcd.pem; do
       scp /etc/etcd/ssl/${FILE} $NODE:/etc/etcd/ssl/${FILE}
     done
 done
​
# 编辑配置文件,所有master节点,etcd对磁盘IO要求很高,建议使用高性能存储
## k8s-master-01
## 注意修改涉及name,listen-peer-urls,listen-client-urls,initial-advertise-peer-urls,advertise-client-urls,initial-cluster
cat > /etc/etcd/etcd.config.yml << EOF
name: 'k8s-master-01'
data-dir: /var/lib/etcd
wal-dir: /var/lib/etcd/wal
snapshot-count: 5000
heartbeat-interval: 100
election-timeout: 1000
quota-backend-bytes: 0
listen-peer-urls: 'https://192.168.222.151:2380'
listen-client-urls: 'https://192.168.222.151:2379,http://127.0.0.1:2379'
max-snapshots: 3
max-wals: 5
cors:
initial-advertise-peer-urls: 'https://192.168.222.151:2380'
advertise-client-urls: 'https://192.168.222.151:2379'
discovery:
discovery-fallback: 'proxy'
discovery-proxy:
discovery-srv:
initial-cluster: 'k8s-master-01=https://192.168.222.151:2380,k8s-master-02=https://192.168.222.152:2380,k8s-master-03=https://192.168.222.153:2380'
initial-cluster-token: 'etcd-k8s-cluster'
initial-cluster-state: 'new'
strict-reconfig-check: false
enable-v2: true
enable-pprof: true
proxy: 'off'
proxy-failure-wait: 5000
proxy-refresh-interval: 30000
proxy-dial-timeout: 1000
proxy-write-timeout: 5000
proxy-read-timeout: 0
client-transport-security:
  cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  client-cert-auth: true
  trusted-ca-file: '/etc/kubernetes/pki/etcd/etcd-ca.pem'
  auto-tls: true
peer-transport-security:
  cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  peer-client-cert-auth: true
  trusted-ca-file: '/etc/kubernetes/pki/etcd/etcd-ca.pem'
  auto-tls: true
debug: false
log-package-levels:
log-outputs: [default]
force-new-cluster: false
EOF
​
## k8s-master-02
## 注意修改涉及name,listen-peer-urls,listen-client-urls,initial-advertise-peer-urls,advertise-client-urls,initial-cluster
cat > /etc/etcd/etcd.config.yml << EOF
name: 'k8s-master-02'
data-dir: /var/lib/etcd
wal-dir: /var/lib/etcd/wal
snapshot-count: 5000
heartbeat-interval: 100
election-timeout: 1000
quota-backend-bytes: 0
listen-peer-urls: 'https://192.168.222.152:2380'
listen-client-urls: 'https://192.168.222.152:2379,http://127.0.0.1:2379'
max-snapshots: 3
max-wals: 5
cors:
initial-advertise-peer-urls: 'https://192.168.222.152:2380'
advertise-client-urls: 'https://192.168.222.152:2379'
discovery:
discovery-fallback: 'proxy'
discovery-proxy:
discovery-srv:
initial-cluster: 'k8s-master-01=https://192.168.222.151:2380,k8s-master-02=https://192.168.222.152:2380,k8s-master-03=https://192.168.222.153:2380'
initial-cluster-token: 'etcd-k8s-cluster'
initial-cluster-state: 'new'
strict-reconfig-check: false
enable-v2: true
enable-pprof: true
proxy: 'off'
proxy-failure-wait: 5000
proxy-refresh-interval: 30000
proxy-dial-timeout: 1000
proxy-write-timeout: 5000
proxy-read-timeout: 0
client-transport-security:
  cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  client-cert-auth: true
  trusted-ca-file: '/etc/kubernetes/pki/etcd/etcd-ca.pem'
  auto-tls: true
peer-transport-security:
  cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  peer-client-cert-auth: true
  trusted-ca-file: '/etc/kubernetes/pki/etcd/etcd-ca.pem'
  auto-tls: true
debug: false
log-package-levels:
log-outputs: [default]
force-new-cluster: false
EOF
​
## k8s-master-03
## 注意修改,涉及name,listen-peer-urls,listen-client-urls,initial-advertise-peer-urls,advertise-client-urls,initial-cluster
cat > /etc/etcd/etcd.config.yml << EOF
name: 'k8s-master-03'
data-dir: /var/lib/etcd
wal-dir: /var/lib/etcd/wal
snapshot-count: 5000
heartbeat-interval: 100
election-timeout: 1000
quota-backend-bytes: 0
listen-peer-urls: 'https://192.168.222.153:2380'
listen-client-urls: 'https://192.168.222.153:2379,http://127.0.0.1:2379'
max-snapshots: 3
max-wals: 5
cors:
initial-advertise-peer-urls: 'https://192.168.222.153:2380'
advertise-client-urls: 'https://192.168.222.153:2379'
discovery:
discovery-fallback: 'proxy'
discovery-proxy:
discovery-srv:
initial-cluster: 'k8s-master-01=https://192.168.222.151:2380,k8s-master-02=https://192.168.222.152:2380,k8s-master-03=https://192.168.222.153:2380'
initial-cluster-token: 'etcd-k8s-cluster'
initial-cluster-state: 'new'
strict-reconfig-check: false
enable-v2: true
enable-pprof: true
proxy: 'off'
proxy-failure-wait: 5000
proxy-refresh-interval: 30000
proxy-dial-timeout: 1000
proxy-write-timeout: 5000
proxy-read-timeout: 0
client-transport-security:
  cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  client-cert-auth: true
  trusted-ca-file: '/etc/kubernetes/pki/etcd/etcd-ca.pem'
  auto-tls: true
peer-transport-security:
  cert-file: '/etc/kubernetes/pki/etcd/etcd.pem'
  key-file: '/etc/kubernetes/pki/etcd/etcd-key.pem'
  peer-client-cert-auth: true
  trusted-ca-file: '/etc/kubernetes/pki/etcd/etcd-ca.pem'
  auto-tls: true
debug: false
log-package-levels:
log-outputs: [default]
force-new-cluster: false
EOF
​
# 创建etcd service,三节点一样
cat > /usr/lib/systemd/system/etcd.service << EOF
[Unit]
Description=Etcd Service
Documentation=https://coreos.com/etcd/docs/latest/
After=network.target

[Service]
Type=notify
ExecStart=/usr/local/bin/etcd --config-file=/etc/etcd/etcd.config.yml
Restart=on-failure
RestartSec=10
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
Alias=etcd3.service
EOF
​
​
# 创建etcd的证书目录,将证书文件做个软连接,所有master节点
mkdir -p /etc/kubernetes/pki/etcd
ln -s /etc/etcd/ssl/* /etc/kubernetes/pki/etcd/
​
# 启动应用
systemctl daemon-reload
systemctl enable --now etcd
​
# 查看状态
export ETCDCTL_API=3
etcdctl --endpoints="192.168.222.151:2379,192.168.222.152:2379,192.168.222.153:2379" --cacert=/etc/kubernetes/pki/etcd/etcd-ca.pem --cert=/etc/kubernetes/pki/etcd/etcd.pem --key=/etc/kubernetes/pki/etcd/etcd-key.pem  endpoint status --write-out=table

复制

4.3、Keepalived,Haproxy安装
# 安装软件,三个master
yum -y install keepalived haproxy
​
# 配置HAProxy,三个节点,配置一样
# 注意修改ip
cat > /etc/haproxy/haproxy.cfg << EOF
global
  maxconn  2000
  ulimit-n  16384
  log  127.0.0.1 local0 err
  stats timeout 30s

defaults
  log global
  mode  http
  option  httplog
  timeout connect 5000
  timeout client  50000
  timeout server  50000
  timeout http-request 15s
  timeout http-keep-alive 15s

frontend k8s-master
  bind 0.0.0.0:8443
  bind 127.0.0.1:8443
  mode tcp
  option tcplog
  tcp-request inspect-delay 5s
  default_backend k8s-master

backend k8s-master
  mode tcp
  option tcplog
  option tcp-check
  balance roundrobin
  default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100
  server k8s-master-01    192.168.222.151:6443  check
  server k8s-master-02    192.168.222.152:6443  check
  server k8s-master-03    192.168.222.153:6443  check
EOF
​
# 配置keepalived,三节点不一样
## k8s-master-01
## 注意修改ip,网卡名称
cat > /etc/keepalived/keepalived.conf << EOF
! Configuration File for keepalived
global_defs {
    router_id LVS_DEVEL
}
vrrp_script chk_apiserver {
    script "/etc/keepalived/check_apiserver.sh"
    interval 5
    weight -5
    fall 2
    rise 1
}
vrrp_instance VI_1 {
    state MASTER
    interface ens33
    mcast_src_ip 192.168.222.151
    virtual_router_id 51
    priority 101
    nopreempt
    advert_int 2
    authentication {
        auth_type PASS
        auth_pass K8SHA_KA_AUTH
    }
    virtual_ipaddress {
        192.168.222.150
    }
    track_script {
      chk_apiserver
} }
EOF
​
## k8s-master-02
## 注意修改ip,网卡名称
cat > /etc/keepalived/keepalived.conf << EOF
! Configuration File for keepalived
global_defs {
    router_id LVS_DEVEL
}
vrrp_script chk_apiserver {
    script "/etc/keepalived/check_apiserver.sh"
    interval 5
    weight -5
    fall 2
    rise 1

}
vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    mcast_src_ip 192.168.222.152
    virtual_router_id 51
    priority 100
    nopreempt
    advert_int 2
    authentication {
        auth_type PASS
        auth_pass K8SHA_KA_AUTH
    }
    virtual_ipaddress {
        192.168.222.150
    }
    track_script {
      chk_apiserver
} }
EOF
​
## k8s-master-03
## 注意修改ip,网卡名称
cat > /etc/keepalived/keepalived.conf << EOF
! Configuration File for keepalived
global_defs {
    router_id LVS_DEVEL
}
vrrp_script chk_apiserver {
    script "/etc/keepalived/check_apiserver.sh"
    interval 5
    weight -5
    fall 2
    rise 1
}
vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    mcast_src_ip 192.168.222.153
    virtual_router_id 51
    priority 100
    nopreempt
    advert_int 2
    authentication {
        auth_type PASS
        auth_pass K8SHA_KA_AUTH
    }
    virtual_ipaddress {
        192.168.222.150
    }
    track_script {
      chk_apiserver
} }
EOF
​
# 健康检测脚本,三节点
cat > /etc/keepalived/check_apiserver.sh << EOF
#!/bin/bash

err=0
for k in $(seq 1 3)
do
    check_code=$(pgrep haproxy)
    if [[ $check_code == "" ]]; then
        err=$(expr $err + 1)
        sleep 1
        continue
    else
        err=0
        break
    fi
done

if [[ $err != "0" ]]; then
    echo "systemctl stop keepalived"
    /usr/bin/systemctl stop keepalived
    exit 1
else
    exit 0
fi
EOF
​
# 给执行权限
chmod +x /etc/keepalived/check_apiserver.sh
​
# 所有master节点启动haproxy和keepalived
systemctl enable --now haproxy
systemctl enable --now keepalived
​
# 验证
ping 192.168.222.150

五、k8s组件安装,master部分

5.1、二进制文件下载安装

解压k8s安装文件,三个master节点

# 下载k8s安装包,以目前最新的1.22.4为例
wget https://storage.googleapis.com/kubernetes-release/release/v1.22.4/kubernetes-server-linux-amd64.tar.gz
​
# 解压安装
tar -xf kubernetes-server-linux-amd64.tar.gz  --strip-components=3 -C /usr/local/bin kubernetes/server/bin/kube{let,ctl,-apiserver,-controller-manager,-scheduler,-proxy}
5.2、证书签发,在k8s-master-01签发,然后复制到其他节点
# 所有master节点创建k8s证书目录
mkdir -p /etc/kubernetes/pki
​
# 创建ca csr
cat > ca-csr.json << EOF
{
  "CN": "kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Hebei",
      "L": "Qinghuangdao",
      "O": "Kubernetes",
      "OU": "Kubernetes"
    }
  ],
  "ca": {
    "expiry": "876000h"
  }
}
EOF
​
# 生成ca证书和ca证书的key
cfssl gencert -initca ca-csr.json | cfssljson -bare /etc/kubernetes/pki/ca
​
# 创建ca config
cat > ca-config.json << EOF
{
  "signing": {
    "default": {
      "expiry": "876000h"
    },
    "profiles": {
      "kubernetes": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "876000h"
      }
    }
  }
}
EOF
​
# 创建apiserver csr
cat > apiserver-csr.json << EOF
{
  "CN": "kube-apiserver",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Hebei",
      "L": "Qinghuangdao",
      "O": "Kubernetes",
      "OU": "Kubernetes"
    }
  ]
}
EOF
​
# 签发apiserver证书
# 10.96.0.0 service网段第一个IP
# 192.168.222.150 VIP地址
cfssl gencert   -ca=/etc/kubernetes/pki/ca.pem   -ca-key=/etc/kubernetes/pki/ca-key.pem   -config=ca-config.json   -hostname=10.96.0.1,192.168.222.150,127.0.0.1,kubernetes,kubernetes.default,kubernetes.default.svc,kubernetes.default.svc.cluster,kubernetes.default.svc.cluster.local,192.168.222.151,192.168.222.152,192.168.222.153  -profile=kubernetes apiserver-csr.json | cfssljson -bare /etc/kubernetes/pki/apiserver
​
# 创建apiserver聚合证书的ca csr
cat > front-proxy-ca-csr.json << EOF
{
  "CN": "kubernetes",
  "key": {
     "algo": "rsa",
     "size": 2048
  }
}
EOF
​
# 签发apiserver聚合证书
# 生成ca证书和ca证书的key
cfssl gencert   -initca front-proxy-ca-csr.json | cfssljson -bare /etc/kubernetes/pki/front-proxy-ca
​
# 创建apiserver聚合证书和key
cat > front-proxy-client-csr.json << EOF
{
  "CN": "front-proxy-client",
  "key": {
     "algo": "rsa",
     "size": 2048
  }
}
EOF
​
# 签发apiserver聚合证书
cfssl gencert   -ca=/etc/kubernetes/pki/front-proxy-ca.pem   -ca-key=/etc/kubernetes/pki/front-proxy-ca-key.pem   -config=ca-config.json   -profile=kubernetes   front-proxy-client-csr.json | cfssljson -bare /etc/kubernetes/pki/front-proxy-client
​
# 创建manager csr
cat > manager-csr.json << EOF
{
  "CN": "system:kube-controller-manager",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Hebei",
      "L": "Qinghuangdao",
      "O": "system:kube-controller-manager",
      "OU": "Kubernetes"
    }
  ]
}
EOF
​
# 签发controller-manage的证书
cfssl gencert\
   -ca=/etc/kubernetes/pki/ca.pem\
   -ca-key=/etc/kubernetes/pki/ca-key.pem\
   -config=ca-config.json\
   -profile=kubernetes\
   manager-csr.json | cfssljson -bare /etc/kubernetes/pki/controller-manager
​
# 创建scheduler csr
cat > scheduler-csr.json << EOF
{
  "CN": "system:kube-scheduler",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Hebei",
      "L": "Qinghuangdao",
      "O": "system:kube-scheduler",
      "OU": "Kubernetes"
    }
  ]
}
EOF
​
# 签发scheduler证书
cfssl gencert\
   -ca=/etc/kubernetes/pki/ca.pem\
   -ca-key=/etc/kubernetes/pki/ca-key.pem\
   -config=ca-config.json\
   -profile=kubernetes\
   scheduler-csr.json | cfssljson -bare /etc/kubernetes/pki/scheduler
​
# 创建admin csr
cat > admin-csr.json << EOF
{
  "CN": "admin",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Hebei",
      "L": "Qinghuangdao",
      "O": "system:masters",
      "OU": "Kubernetes"
    }
  ]
}
EOF
​
# 签发admin证书
cfssl gencert\
   -ca=/etc/kubernetes/pki/ca.pem\
   -ca-key=/etc/kubernetes/pki/ca-key.pem\
   -config=ca-config.json\
   -profile=kubernetes\
   admin-csr.json | cfssljson -bare /etc/kubernetes/pki/admin
​
# 创建ServiceAccount Key
openssl genrsa -out /etc/kubernetes/pki/sa.key 2048
openssl rsa -in /etc/kubernetes/pki/sa.key -pubout -out /etc/kubernetes/pki/sa.pub
5.3、k8s组件配置,在k8s-master-01节点执行
# controller-manage配置
# 设置一个集群项
kubectl config set-cluster kubernetes\
     --certificate-authority=/etc/kubernetes/pki/ca.pem\
     --embed-certs=true\
     --server=https://192.168.222.150:8443\
     --kubeconfig=/etc/kubernetes/controller-manager.kubeconfig
​
# set-credentials 设置一个用户项
kubectl config set-credentials system:kube-controller-manager\
     --client-certificate=/etc/kubernetes/pki/controller-manager.pem\
     --client-key=/etc/kubernetes/pki/controller-manager-key.pem\
     --embed-certs=true\
     --kubeconfig=/etc/kubernetes/controller-manager.kubeconfig
​
# 设置一个环境项
kubectl config set-context system:kube-controller-manager@kubernetes\
    --cluster=kubernetes\
    --user=system:kube-controller-manager\
    --kubeconfig=/etc/kubernetes/controller-manager.kubeconfig
​
# 设置默认环境
kubectl config use-context system:kube-controller-manager@kubernetes\
     --kubeconfig=/etc/kubernetes/controller-manager.kubeconfig
# scheduler配置
# 设置一个集群项
kubectl config set-cluster kubernetes\
     --certificate-authority=/etc/kubernetes/pki/ca.pem\
     --embed-certs=true\
     --server=https://192.168.222.150:8443\
     --kubeconfig=/etc/kubernetes/scheduler.kubeconfig
​
# set-credentials 设置一个用户项
kubectl config set-credentials system:kube-scheduler\
     --client-certificate=/etc/kubernetes/pki/scheduler.pem\
     --client-key=/etc/kubernetes/pki/scheduler-key.pem\
     --embed-certs=true\
     --kubeconfig=/etc/kubernetes/scheduler.kubeconfig
​
# 设置一个环境项
kubectl config set-context system:kube-scheduler@kubernetes\
     --cluster=kubernetes\
     --user=system:kube-scheduler\
     --kubeconfig=/etc/kubernetes/scheduler.kubeconfig
​
# 设置默认环境
kubectl config use-context system:kube-scheduler@kubernetes\
     --kubeconfig=/etc/kubernetes/scheduler.kubeconfig
# admin配置
# 设置一个集群项
kubectl config set-cluster kubernetes\
    --certificate-authority=/etc/kubernetes/pki/ca.pem\
    --embed-certs=true\
    --server=https://192.168.222.150:8443\
    --kubeconfig=/etc/kubernetes/admin.kubeconfig

# set-credentials 设置一个用户项
kubectl config set-credentials kubernetes-admin\
    --client-certificate=/etc/kubernetes/pki/admin.pem\
    --client-key=/etc/kubernetes/pki/admin-key.pem\
    --embed-certs=true\
    --kubeconfig=/etc/kubernetes/admin.kubeconfig
​
# 设置一个环境项
kubectl config set-context kubernetes-admin@kubernetes\
    --cluster=kubernetes\
    --user=kubernetes-admin\
    --kubeconfig=/etc/kubernetes/admin.kubeconfig
​
# 设置默认环境
kubectl config use-context kubernetes-admin@kubernetes\
    --kubeconfig=/etc/kubernetes/admin.kubeconfig
# 复制证书以及配置文件到其他master节点
for NODE in k8s-master-02 k8s-master-03; do
    for FILE in $(ls /etc/kubernetes/pki | grep -v etcd); do
        scp /etc/kubernetes/pki/${FILE} $NODE:/etc/kubernetes/pki/${FILE};
    done;
    for FILE in admin.kubeconfig controller-manager.kubeconfig scheduler.kubeconfig; do
        scp /etc/kubernetes/${FILE} $NODE:/etc/kubernetes/${FILE};
    done;
done
# APIserver配置
# 创建相关目录,所有master节点
mkdir -p /etc/kubernetes/manifests/ /etc/systemd/system/kubelet.service.d /var/lib/kubelet /var/log/kubernetes
​
# 创建apiserver service,三节点文件不一样
# k8s-master-01
# 注意修改IP
# 注意service-cluster-ip-range设置为service网段
​
cat > /usr/lib/systemd/system/kube-apiserver.service << EOF

[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
ExecStart=/usr/local/bin/kube-apiserver\
      --v=2\
      --logtostderr=true\
      --allow-privileged=true\
      --bind-address=0.0.0.0\
      --secure-port=6443\
      --insecure-port=0\
      --advertise-address=192.168.222.151\
      --service-cluster-ip-range=10.96.0.0/16\
      --service-node-port-range=30000-32767\
      --etcd-servers=https://192.168.222.151:2379,https://192.168.222.152:2379,https://192.168.222.153:2379\
      --etcd-cafile=/etc/etcd/ssl/etcd-ca.pem\
      --etcd-certfile=/etc/etcd/ssl/etcd.pem\
      --etcd-keyfile=/etc/etcd/ssl/etcd-key.pem\
      --client-ca-file=/etc/kubernetes/pki/ca.pem\
      --tls-cert-file=/etc/kubernetes/pki/apiserver.pem\
      --tls-private-key-file=/etc/kubernetes/pki/apiserver-key.pem\
      --kubelet-client-certificate=/etc/kubernetes/pki/apiserver.pem\
      --kubelet-client-key=/etc/kubernetes/pki/apiserver-key.pem\
      --service-account-key-file=/etc/kubernetes/pki/sa.pub\
      --service-account-signing-key-file=/etc/kubernetes/pki/sa.key\
      --service-account-issuer=https://kubernetes.default.svc.cluster.local\
      --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname\
      --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,ResourceQuota\
      --authorization-mode=Node,RBAC\
      --enable-bootstrap-token-auth=true\
      --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem\
      --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.pem\
      --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client-key.pem\
      --requestheader-allowed-names=aggregator\
      --requestheader-group-headers=X-Remote-Group\
      --requestheader-extra-headers-prefix=X-Remote-Extra-\
      --requestheader-username-headers=X-Remote-User

Restart=on-failure
RestartSec=10s
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
EOF
​
# k8s-master-02
# 注意service-cluster-ip-range设置为service网段
cat > /usr/lib/systemd/system/kube-apiserver.service << EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
ExecStart=/usr/local/bin/kube-apiserver\
      --v=2\
      --logtostderr=true\
      --allow-privileged=true\
      --bind-address=0.0.0.0\
      --secure-port=6443\
      --insecure-port=0\
      --advertise-address=192.168.222.152\
      --service-cluster-ip-range=10.96.0.0/16\
      --service-node-port-range=30000-32767\
      --etcd-servers=https://192.168.222.151:2379,https://192.168.222.152:2379,https://192.168.222.153:2379\
      --etcd-cafile=/etc/etcd/ssl/etcd-ca.pem\
      --etcd-certfile=/etc/etcd/ssl/etcd.pem\
      --etcd-keyfile=/etc/etcd/ssl/etcd-key.pem\
      --client-ca-file=/etc/kubernetes/pki/ca.pem\
      --tls-cert-file=/etc/kubernetes/pki/apiserver.pem\
      --tls-private-key-file=/etc/kubernetes/pki/apiserver-key.pem\
      --kubelet-client-certificate=/etc/kubernetes/pki/apiserver.pem\
      --kubelet-client-key=/etc/kubernetes/pki/apiserver-key.pem\
      --service-account-key-file=/etc/kubernetes/pki/sa.pub\
      --service-account-signing-key-file=/etc/kubernetes/pki/sa.key\
      --service-account-issuer=https://kubernetes.default.svc.cluster.local\
      --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname\
      --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,ResourceQuota\
      --authorization-mode=Node,RBAC\
      --enable-bootstrap-token-auth=true\
      --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem\
      --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.pem\
      --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client-key.pem\
      --requestheader-allowed-names=aggregator\
      --requestheader-group-headers=X-Remote-Group\
      --requestheader-extra-headers-prefix=X-Remote-Extra-\
      --requestheader-username-headers=X-Remote-User
​
Restart=on-failure
RestartSec=10s
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
EOF
​
# k8s-master-03
# 注意service-cluster-ip-range设置为service网段
cat > /usr/lib/systemd/system/kube-apiserver.service << EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
ExecStart=/usr/local/bin/kube-apiserver\
      --v=2\
      --logtostderr=true\
      --allow-privileged=true\
      --bind-address=0.0.0.0\
      --secure-port=6443\
      --insecure-port=0\
      --advertise-address=192.168.222.153\
      --service-cluster-ip-range=10.96.0.0/16\
      --service-node-port-range=30000-32767\
      --etcd-servers=https://192.168.222.151:2379,https://192.168.222.152:2379,https://192.168.222.153:2379\
      --etcd-cafile=/etc/etcd/ssl/etcd-ca.pem\
      --etcd-certfile=/etc/etcd/ssl/etcd.pem\
      --etcd-keyfile=/etc/etcd/ssl/etcd-key.pem\
      --client-ca-file=/etc/kubernetes/pki/ca.pem\
      --tls-cert-file=/etc/kubernetes/pki/apiserver.pem\
      --tls-private-key-file=/etc/kubernetes/pki/apiserver-key.pem\
      --kubelet-client-certificate=/etc/kubernetes/pki/apiserver.pem\
      --kubelet-client-key=/etc/kubernetes/pki/apiserver-key.pem\
      --service-account-key-file=/etc/kubernetes/pki/sa.pub\
      --service-account-signing-key-file=/etc/kubernetes/pki/sa.key\
      --service-account-issuer=https://kubernetes.default.svc.cluster.local\
      --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname\
      --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,NodeRestriction,ResourceQuota\
      --authorization-mode=Node,RBAC\
      --enable-bootstrap-token-auth=true\
      --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem\
      --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.pem\
      --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client-key.pem\
      --requestheader-allowed-names=aggregator\
      --requestheader-group-headers=X-Remote-Group\
      --requestheader-extra-headers-prefix=X-Remote-Extra-\
      --requestheader-username-headers=X-Remote-User

Restart=on-failure
RestartSec=10s
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
EOF
​
# 启动apiserver
systemctl daemon-reload
systemctl enable --now kube-apiserver
​
# 查看状态
systemctl status kube-apiserver
# 创建ControllerManage service,所有节点一样
# 注意cluster-cidr设置为pod网段
cat > /usr/lib/systemd/system/kube-controller-manager.service << EOF
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
ExecStart=/usr/local/bin/kube-controller-manager\
      --v=2\
      --logtostderr=true\
      --address=127.0.0.1\
      --root-ca-file=/etc/kubernetes/pki/ca.pem\
      --cluster-signing-cert-file=/etc/kubernetes/pki/ca.pem\
      --cluster-signing-key-file=/etc/kubernetes/pki/ca-key.pem\
      --service-account-private-key-file=/etc/kubernetes/pki/sa.key\
      --kubeconfig=/etc/kubernetes/controller-manager.kubeconfig\
      --leader-elect=true\
      --use-service-account-credentials=true\
      --node-monitor-grace-period=40s\
      --node-monitor-period=5s\
      --pod-eviction-timeout=2m0s\
      --controllers=*,bootstrapsigner,tokencleaner\
      --allocate-node-cidrs=true\
      --cluster-cidr=10.244.0.0/12\
      --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem\
      --node-cidr-mask-size=24

Restart=always
RestartSec=10s

[Install]
WantedBy=multi-user.target
EOF

# 启动ControllerManage
systemctl daemon-reload
systemctl enable --now kube-controller-manager

# 查看状态
systemctl  status kube-controller-manager
# 创建Scheduler service,所有master节点配置一样
cat > /usr/lib/systemd/system/kube-scheduler.service << EOF
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
ExecStart=/usr/local/bin/kube-scheduler\
      --v=2\
      --logtostderr=true\
      --address=127.0.0.1\
      --leader-elect=true\
      --kubeconfig=/etc/kubernetes/scheduler.kubeconfig

Restart=always
RestartSec=10s

[Install]
WantedBy=multi-user.target
EOF
​
# 启动应用
systemctl daemon-reload
systemctl enable --now kube-scheduler
​
# 查看状态
systemctl  status kube-scheduler
5.4、TLS Bootstrapping

用于kubelet证书自动签发,只在k8s-master-01节点操作

# 生成token格式字符串(长度不符,内容符合),取前六位作为令牌id,后16位作为令牌秘密(随便怎么截取,长度对就行)
# fe8a9b6548d78692a5682c122d2291e3
# id:fe8a9b
# secret: a5682c122d2291e3
head -c 16 /dev/urandom | od -An -t x | tr -d ' '
​
# 设置一个集群项
kubectl config set-cluster kubernetes\
    --certificate-authority=/etc/kubernetes/pki/ca.pem\
    --embed-certs=true\
    --server=https://192.168.222.150:8443\
    --kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig
​
# set-credentials 设置一个用户项
kubectl config set-credentials tls-bootstrap-token-user\
    --token=fe8a9b.a5682c122d2291e3\
    --kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig
​
# 设置一个环境项
kubectl config set-context tls-bootstrap-token-user@kubernetes\
    --cluster=kubernetes\
    --user=tls-bootstrap-token-user\
    --kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig
​
# 设置默认环境
kubectl config use-context tls-bootstrap-token-user@kubernetes\
    --kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig
​
# 设置admin环境变量,用户kubectl访问集群
mkdir -p /root/.kube
cp /etc/kubernetes/admin.kubeconfig /root/.kube/config
​
​
# 创建bootstrap.secret.yaml
# 注意metadata.name,和上面的token保持一致
# 主机stringData.token-id,和上面的token保持一致
# 主机stringData.token-secret,和上面的token保持一致
cat > bootstrap.secret.yaml  << EOF
apiVersion: v1
kind: Secret
metadata:
  name: bootstrap-token-fe8a9b
  namespace: kube-system
type: bootstrap.kubernetes.io/token
stringData:
  description: "The default bootstrap token generated by 'kubelet '."
  token-id: fe8a9b
  token-secret: a5682c122d2291e3
  usage-bootstrap-authentication: "true"
  usage-bootstrap-signing: "true"
  auth-extra-groups:  system:bootstrappers:default-node-token,system:bootstrappers:worker,system:bootstrappers:ingress

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kubelet-bootstrap
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:node-bootstrapper
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: system:bootstrappers:default-node-token
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: node-autoapprove-bootstrap
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:certificates.k8s.io:certificatesigningrequests:nodeclient
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: system:bootstrappers:default-node-token
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: node-autoapprove-certificate-rotation
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: system:nodes
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: system:kube-apiserver-to-kubelet
rules:
  - apiGroups:
      - ""
    resources:
      - nodes/proxy
      - nodes/stats
      - nodes/log
      - nodes/spec
      - nodes/metrics
    verbs:
      - "*"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: system:kube-apiserver
  namespace: ""
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:kube-apiserver-to-kubelet
subjects:
  - apiGroup: rbac.authorization.k8s.io
    kind: User
    name: kube-apiserver
EOF
​
# 创建bootstrap相关资源
kubectl create -f bootstrap.secret.yaml

六、k8s组件安装,master和node

6.1、复制证书文件
for NODE in k8s-master-02 k8s-master-03 k8s-node-01 k8s-node-02; do
    ssh $NODE mkdir -p /etc/kubernetes/pki /etc/etcd/ssl
    for FILE in etcd-ca.pem etcd.pem etcd-key.pem; do
        scp /etc/etcd/ssl/$FILE $NODE:/etc/etcd/ssl/
    done
    for FILE in pki/ca.pem pki/ca-key.pem pki/front-proxy-ca.pem bootstrap-kubelet.kubeconfig; do
        scp /etc/kubernetes/$FILE $NODE:/etc/kubernetes/${FILE}
    done
 done
6.2、node节点安装k8s二进制文件

解压k8s安装文件,所有node节点

# 下载k8s安装包,以目前最新的1.22.4为例
wget https://storage.googleapis.com/kubernetes-release/release/v1.22.4/kubernetes-server-linux-amd64.tar.gz
​
# 解压安装
tar -xf kubernetes-server-linux-amd64.tar.gz  --strip-components=3 -C /usr/local/bin kubernetes/server/bin/kube{let,-proxy}
6.3、Kubelet配置,所有节点包括master和node
# 创建目录
mkdir -p /var/lib/kubelet /var/log/kubernetes /etc/systemd/system/kubelet.service.d /etc/kubernetes/manifests/
​
# 创建kubelet service,所有节点一样
cat > /usr/lib/systemd/system/kubelet.service << EOF
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=docker.service
Requires=docker.service

[Service]
ExecStart=/usr/local/bin/kubelet

Restart=always
StartLimitInterval=0
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF
​
# 创建kubelet service配置文件,所有节点一样
cat > /etc/systemd/system/kubelet.service.d/10-kubelet.conf << EOF
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig --kubeconfig=/etc/kubernetes/kubelet.kubeconfig"
Environment="KUBELET_SYSTEM_ARGS=--network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin"
Environment="KUBELET_CONFIG_ARGS=--config=/etc/kubernetes/kubelet-conf.yml --pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.5"
Environment="KUBELET_EXTRA_ARGS=--node-labels=node.kubernetes.io/node='' "
ExecStart=
ExecStart=/usr/local/bin/kubelet \$KUBELET_KUBECONFIG_ARGS \$KUBELET_CONFIG_ARGS \$KUBELET_SYSTEM_ARGS \$KUBELET_EXTRA_ARGS
EOF
​
# 创建kubelet配置文件,所有节点一样
# clusterDNS设置为service网段第10个IP
cat > /etc/kubernetes/kubelet-conf.yml << EOF
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
address: 0.0.0.0
port: 10250
readOnlyPort: 10255
authentication:
  anonymous:
    enabled: false
  webhook:
    cacheTTL: 2m0s
    enabled: true
  x509:
    clientCAFile: /etc/kubernetes/pki/ca.pem
authorization:
  mode: Webhook
  webhook:
    cacheAuthorizedTTL: 5m0s
    cacheUnauthorizedTTL: 30s
cgroupDriver: systemd
cgroupsPerQOS: true
clusterDNS:
- 10.92.0.10
clusterDomain: cluster.local
containerLogMaxFiles: 5
containerLogMaxSize: 10Mi
contentType: application/vnd.kubernetes.protobuf
cpuCFSQuota: true
cpuManagerPolicy: none
cpuManagerReconcilePeriod: 10s
enableControllerAttachDetach: true
enableDebuggingHandlers: true
enforceNodeAllocatable:
- pods
eventBurst: 10
eventRecordQPS: 5
evictionHard:
  imagefs.available: 15%
  memory.available: 100Mi
  nodefs.available: 10%
  nodefs.inodesFree: 5%
evictionPressureTransitionPeriod: 5m0s
failSwapOn: true
fileCheckFrequency: 20s
hairpinMode: promiscuous-bridge
healthzBindAddress: 127.0.0.1
healthzPort: 10248
httpCheckFrequency: 20s
imageGCHighThresholdPercent: 85
imageGCLowThresholdPercent: 80
imageMinimumGCAge: 2m0s
iptablesDropBit: 15
iptablesMasqueradeBit: 14
kubeAPIBurst: 10
kubeAPIQPS: 5
makeIPTablesUtilChains: true
maxOpenFiles: 1000000
maxPods: 110
nodeStatusUpdateFrequency: 10s
oomScoreAdj: -999
podPidsLimit: -1
registryBurst: 10
registryPullQPS: 5
resolvConf: /etc/resolv.conf
rotateCertificates: true
runtimeRequestTimeout: 2m0s
serializeImagePulls: true
staticPodPath: /etc/kubernetes/manifests
streamingConnectionIdleTimeout: 4h0m0s
syncFrequency: 1m0s
volumeStatsAggPeriod: 1m0s
EOF
​
# 启动kubelet
systemctl daemon-reload
systemctl enable --now kubelet
6.4、kube-proxy
# 只在Master01执行
kubectl -n kube-system create serviceaccount kube-proxy
​
kubectl create clusterrolebinding system:kube-proxy\
    --clusterrole system:node-proxier\
    --serviceaccount kube-system:kube-proxy
​
SECRET=$(kubectl -n kube-system get sa/kube-proxy\
    --output=jsonpath='{.secrets[0].name}')
​
JWT_TOKEN=$(kubectl -n kube-system get secret/$SECRET\
--output=jsonpath='{.data.token}' | base64 -d)
​
# 设置一个集群项
kubectl config set-cluster kubernetes\
    --certificate-authority=/etc/kubernetes/pki/ca.pem\
    --embed-certs=true\
    --server=https://192.168.222.150:8443\
    --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig
​
# set-credentials 设置一个用户项
kubectl config set-credentials kubernetes\
    --token=${JWT_TOKEN}\
    --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig
​
# 设置一个环境项
kubectl config set-context kubernetes\
    --cluster=kubernetes\
    --user=kubernetes\
    --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig
​
# 设置默认环境
kubectl config use-context kubernetes --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig
​
# 复制配置文件至其他节点
for NODE in k8s-master-02 k8s-master-03 k8s-node-01 k8s-node-02; do
     scp /etc/kubernetes/kube-proxy.kubeconfig  $NODE:/etc/kubernetes/kube-proxy.kubeconfig
done
​
# 创建kube-proxy service,所有节点一样
cat > /usr/lib/systemd/system/kube-proxy.service << EOF
[Unit]
Description=Kubernetes Kube Proxy
Documentation=https://github.com/kubernetes/kubernetes
After=network.target

[Service]
ExecStart=/usr/local/bin/kube-proxy\
  --config=/etc/kubernetes/kube-proxy.yaml\
  --v=2

Restart=always
RestartSec=10s

[Install]
WantedBy=multi-user.target
EOF
​
# kube-proxy配置文件,所有节点一样
# clusterCIDR设置为pod网段
cat > /etc/kubernetes/kube-proxy.yaml << EOF
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0
clientConnection:
  acceptContentTypes: ""
  burst: 10
  contentType: application/vnd.kubernetes.protobuf
  kubeconfig: /etc/kubernetes/kube-proxy.kubeconfig
  qps: 5
clusterCIDR: 10.244.0.0/12
configSyncPeriod: 15m0s
conntrack:
  max: null
  maxPerCore: 32768
  min: 131072
  tcpCloseWaitTimeout: 1h0m0s
  tcpEstablishedTimeout: 24h0m0s
enableProfiling: false
healthzBindAddress: 0.0.0.0:10256
hostnameOverride: ""
iptables:
  masqueradeAll: false
  masqueradeBit: 14
  minSyncPeriod: 0s
  syncPeriod: 30s
ipvs:
  masqueradeAll: true
  minSyncPeriod: 5s
  scheduler: "rr"
  syncPeriod: 30s
kind: KubeProxyConfiguration
metricsBindAddress: 127.0.0.1:10249
mode: "ipvs"
nodePortAddresses: null
oomScoreAdj: -999
portRange: ""
udpIdleTimeout: 250ms
EOF
​
# 启动kube-proxy,所有节点
systemctl daemon-reload
systemctl enable --now kube-proxy
6.5、安装Calico
# 依据k8s版本的changelog选择calico版本
# k8s1.22.4版本changelog:https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.22.md#changelog-since-v1223
# calico3.19版本说明页:https://docs.projectcalico.org/archive/v3.19/getting-started/kubernetes/self-managed-onprem/onpremises
# 下载calico.yaml
curl https://docs.projectcalico.org/archive/v3.19/manifests/calico-typha.yaml -o calico.yaml
​
# 修改pod网段
# 取消对清单中的 CALICO_IPV4POOL_CIDR 变量的注释,并将其设置为与您选择的 pod CIDR 相同的值。
vim calico.yaml
​
## 修改内容如下
- name: CALICO_IPV4POOL_CIDR
  value: "10.244.0.0/12"
​
# 安装
kubectl apply -f calico.yaml
​
# 查看状态,确认状态都是running后继续
kubectl get po -n kube-system
6.6、安装CoreDNS
# 依据k8s版本的changelog选择coreDns版本
# k8s1.22.4版本changelog:https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.22.md#changelog-since-v1223
# coreDns安装工具,没有对应版本(1.8.4)只保留最新版1.8.6:https://github.com/coredns/deployment
# 根据提交日志找到1.8.4版本的提交记录:https://github.com/coredns/deployment/tree/e13bd2af8c2b2ff4dc18f9be3071f2033f96a70f
# 下载项目,git下载不了就直接页面下载zip包
git clone https://github.com/coredns/deployment.git
​
# 生成yaml,10.96.0.10是k8s service网段的第十个IP
cd deployment/kubernetes
chmod 755 deploy.sh
./deploy.sh -s -i 10.96.0.10 > coredns.yaml
​
# 对比历史提交记录,生成的yaml和1.8.4版本只相差一个镜像版本,修改yaml中的使用镜像
vim coredns.yaml
​
## 修改内容
image: coredns/coredns:1.8.6  --> image: coredns/coredns:1.8.4
​
# 安装,镜像需要梯子
kubectl  create -f coredns.yaml
​
# 查看状态
kubectl get po -n kube-system -l k8s-app=kube-dns
​
# 在集群环境中单节点的CoreDns存在负载压力以及单点故障,应该配置为自动扩展
# 官方文档:https://kubernetes.io/docs/tasks/administer-cluster/dns-horizontal-autoscaling/
# 复制官方文档中的yaml,需要梯子
curl https://raw.githubusercontent.com/kubernetes/website/main/content/en/examples/admin/dns/dns-horizontal-autoscaler.yaml -o dns-horizontal-autoscaler.yaml
​
# 修改yaml
vim dns-horizontal-autoscaler.yaml
​
# 修改内容
<SCALE_TARGET>,替换为Deployment/coredns
​
# 应用自动扩展,镜像需要梯子
kubectl apply -f dns-horizontal-autoscaler.yaml
​
# 验证,coredns pod数量应该已经自动扩展
kubectl get deployment --namespace=kube-system
6.7、安装Metrics Server
# Kubernetes中系统资源的采集均使用Metrics-server,可以通过Metrics采集节点和Pod的内存、磁盘、CPU和网络的使用率。
# https://github.com/kubernetes-sigs/metrics-server
# 下载yaml文件
https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.5.2/components.yaml
​
# 修改
vim components.yaml
​
## 修改内容
### 启动参数添加证书配置
      - args:
        - --cert-dir=/tmp
        - --secure-port=4443
        - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
        - --kubelet-use-node-status-port
        - --metric-resolution=15s
        - --kubelet-insecure-tls
        - --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.pem # change to front-proxy-ca.crt for kubeadm
        - --requestheader-username-headers=X-Remote-User
        - --requestheader-group-headers=X-Remote-Group
        - --requestheader-extra-headers-prefix=X-Remote-Extra-

### volume挂载master节点证书文件
        volumeMounts:
        - mountPath: /tmp
          name: tmp-dir
        - name: ca-ssl
          mountPath: /etc/kubernetes/pki
      nodeSelector:
        kubernetes.io/os: linux
      priorityClassName: system-cluster-critical
      serviceAccountName: metrics-server
      volumes:
      - emptyDir: {}
        name: tmp-dir
      - name: ca-ssl
        hostPath:
          path: /etc/kubernetes/pki
​
# 安装
kubectl apply -f components.yaml
​
# 验证
kubectl top node
6.8、安装Dashboard
# 安装
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.4.0/aio/deploy/recommended.yaml
​
# 创建管理用户
cat > admin.yaml << EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kube-system
EOF
​
kubectl apply -f admin.yaml
​
# 修改dashboard的svc,将cluster变更为nodeport
kubectl edit svc -n kubernetes-dashboard kubernetes-dashboard
​
## 修改内容
  type: NodePort
​
# 查看NodePort地址
kubectl get svc -n kubernetes-dashboard
​
# 访问
## 浏览器访问,端口号30865为上一步查询所得,端口号为随机端口号以上面命令查询结果为准
https://192.168.222.151:30865/
​
# 登录验证方式选择token
## 查看token命令
kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')
​

标签: none

添加新评论