k8s二进制方式部署

生产环境部署 K8s 集群的两种方式 :

  • Kubeadm方式: Kubeadm 是一个 K8s 部署工具,提供 kubeadm init 和 kubeadm join,用于快速部署 Kubernetes 集群。
  • 二进制方式: 从 github 下载发行版的二进制包,手动部署每个组件,组成 Kubernetes 集群。

总结: Kubeadm 降低部署门槛,但屏蔽了很多细节,遇到问题很难排查。如果想更容易可控,推荐使用二进制包部署 Kubernetes 集群,虽然部署麻烦,期间可以学习很多工作原理,也利于后期维护。

环境准备:

节点数 系统 docker版本 kubernetes版本
master(3台) centos7 docker-ce 19.03.9 1.20.8
worker(2台) centos7 docker-ce 19.03.9 1.20.8

#注意:master节点至少要2个cpu,否则报错 error execution phase preflight: [preflight] Some fatal errors occurred: [ERROR NumCPU]: the number of available CPUs 1 is less than the required 2

操作系统初始化设置:

1、修改/etc/hosts,设置主机名,添加内容如下:
192.168.15.215 k8s-master01
192.168.15.216 k8s-master02
192.168.15.217 k8s-master03
192.168.15.218 k8s-worker1
192.168.15.219 k8s-worker2
2、 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
systemctl stop NetworkManager        #关闭后calico才可以管理网卡,否则有影响
systemctl disable NetworkManager
3、关闭 selinux
sed -i 's/enforcing/disabled/' /etc/selinux/config # 永久
setenforce 0                                       # 临时
4、关闭 swap
#swap开启会影响k8s编排和调度应用程序运行的效果,会降低性能
swapoff -a                                         # 临时
sed -ri '/^[^#]*swap/s@^@#@' /etc/fstab            # 永久
5、将桥接的 IPv4 流量传递到 iptables 的链
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system                                     # 生效
6、安装常用工具:
yum -y install wget jq psmisc vim net-tools  telnet yum-utils device-mapper-persistent-data lvm2 git network-scripts tar curl
7、时间同步
#各个节点需要通过时间服务器保持时间同步
yum install ntpdate -y
ntpdate time.windows.com  或者 ntpdate -u cn.pool.ntp.org(中国ntp服务器)
8、修改内核参数文件/etc/security/limits.conf,添加内容如下:
cat >> /etc/security/limits.conf <<EOF
* soft nofile 65535
* hard nofile 65535
* soft noproc 65535
* hard noproc 65535
* soft memlock unlimited
* hard memlock unlimited
EOF
9、升级一下系统,执行命令如下:
yum update -y  --exclude=kernel* && reboot    #排除内核,下面会单独升级内核
10、升级内核,至少要达到4.18+ 才可以
yum  -y localinstall kernel-ml* (包含kernel-ml-5.17.5-1.el7.elrepo.x86_64.rpm和kernel-ml-devel-5.17.5-1.el7.elrepo.x86_64.rpm两个包)
更改内核启动顺序:
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                                        #最后重启即可

注:内核下载地址:内核下载地址1 、内核下载地址2

11、安装ipvsadm
yum -y install ipvsadm ipset sysstat conntrack libseccomp
内核配置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
#重启系统后查看是否加载
lsmod | grep -e ip_vs -e nf_conntrack

注意:如果内核版本小于4.19,那么配置中的nf_conntrack应该为nf_conntrack_ipv4

12、开启一些k8s集群中必须的内核参数
cat >> /etc/sysctl.d/k8s.conf <<EOF
net.ipv4.ip_forward =1
fs.may_detach_mounts = 1
vm.overcommit_memory = 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_contrack_max = 65536
net.ipv4.tcp_timestamps = 0
net.core.somaxconn = 16384
EOF
#配置完成后,重启服务器,查看内核加载情况
lsmod | grep --color=auto -e ip_vs -e nf_conntrack

一、部署etcd集群:

Etcd 是一个分布式键值存储系统,Kubernetes 使用 Etcd 进行数据存储,所以先 准备一个 Etcd 数据库,为解决 Etcd 单点故障,应采用集群方式部署,这里使用 3 台组建集群,可容忍 1 台机器故障,当然,你也可以使用 5 台组建集群,可容忍 2 台机器故障。 本例子中使用三台master节点机器组成集群

etcd1 192.168.15.215
etcd2 192.168.15.216
etcd3 182.168.15.217

1、 准备 cfssl 证书生成工具 :

cfssl 是一个开源的证书管理工具,使用 json 文件生成证书,相比 openssl 更方便使用。

找任意一台服务器操作,这里用 Master 节点,执行命令如下:

wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64
mv cfssl_linux-amd64 /usr/local/bin/cfssl
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo

2、 生成 Etcd 证书 :

2.1 自签证书颁发机构(CA):

#在当前用户的根目录下创建文件加TLS,里面创建目录etcd和k8s 
mkdir -p ~/TLS/{etcd,k8s} 

自签 CA:

#进入创建的etcd目录中
cd ~/TLS/etcd
#"expiry": "87600h", 表示证书过期时间
cat > etcd-ca-config.json <<EOF
{
    "signing": {
       "default": {
          "expiry": "87600h"
       },
       "profiles": {
           "www": {
              "expiry": "87600h",
              "usages": [
                 "signing",
                 "key encipherment",
                 "server auth",
                 "client auth"
               ]
            }
        }
    }
}
EOF
#再次执行命令创建etcd-ca-csr.json证书请求文件
cat > etcd-ca-csr.json << EOF
{
    "CN": "etcd CA",
    "key": {
       "algo": "rsa",
       "size": 2048
    },
    "names": [
      {
       "C": "CN",
       "L": "Beijing",
       "ST": "Beijing"
      }
    ]
}
EOF

可通过 cat etcd-ca-config.json | jq . 来检查json文件是否正确(需要提前yum -y install jq )

接下来执行如下命令生成证书, 会生成 ca.pem 和 ca-key.pem 文件,如下:

cfssl gencert -initca etcd-ca-csr.json | cfssljson -bare etcd-ca -

2.2 使用自签 CA 签发 Etcd HTTPS 证书 :

创建证书申请文件:

#"192.169.15.*"  表示预留IP 可以写多个
cat > server-csr.json <<EOF
{
 "CN": "etcd",
 "hosts": [
 "192.168.15.215",
 "192.168.15.216",
 "192.168.15.217"
 "192.168.15.*"
 ],
 "key": {
     "algo": "rsa",
     "size": 2048
 },
 "names": [
    {
      "C": "CN",
      "L": "BeiJing",
      "ST": "BeiJing"
    }
 ]
}
EOF

注:上述文件 hosts 字段中 IP 为所有 etcd 节点的集群内部通信 IP,一个都不能 少!为了方便后期扩容可以多写几个预留的 IP。

生成证书, 会生成 server.pem 和 server-key.pem 文件,执行命令如下:

cfssl gencert -ca=etcd-ca.pem -ca-key=etcd-ca-key.pem -config=etcd-ca-config.json -profile=www server-csr.json | cfssljson -bare server

3、下载etcd,地址:https://github.com/etcd-io/etcd/releases/tag/v3.5.0

接下来正式部署etcd,首先现在节点1上操作, 为简化操作,待会将节点 1 生成的所有文件拷贝到节点 2 和 节点 3 上

创建工作目录并解压二进制包:

mkdir /opt/etcd/{bin,cfg,ssl} -p
tar zxvf etcd-v3.5.0-linux-amd64.tar.gz
mv etcd-v3.5.0-linux-amd64/{etcd,etcdctl} /opt/etcd/bin/

创建 etcd 配置文件 :

cat > /opt/etcd/cfg/etcd.conf   <<EOF
#[Member]
ETCD_NAME="etcd-1"
ETCD_DATA_DIR="/opt/etcd/data"
ETCD_LISTEN_PEER_URLS="https://192.168.15.215:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.15.215:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.15.215:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.15.215:2379"
ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.15.215:2380,etcd-2=https://192.168.15.216:2380,etcd-3=https://192.168.15.217:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
EOF

说明:

  • ETCD_NAME:节点名称,集群中唯一
  • ETCD_DATA_DIR:数据目录
  • ETCD_LISTEN_PEER_URLS:集群通信监听地址
  • ETCD_LISTEN_CLIENT_URLS:客户端访问监听地址
  • ETCD_INITIAL_ADVERTISE_PEERURLS:集群通告地址
  • ETCD_ADVERTISE_CLIENT_URLS:客户端通告地址
  • ETCD_INITIAL_CLUSTER:集群节点地址
  • ETCD_INITIALCLUSTER_TOKEN:集群 Token
  • ETCD_INITIALCLUSTER_STATE:加入集群的当前状态,new 是新集群,existing 表示加入已有集群

通过systemd 管理 etcd :

cat > /usr/lib/systemd/system/etcd.service << EOF
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
EnvironmentFile=/opt/etcd/cfg/etcd.conf
ExecStart=/opt/etcd/bin/etcd \
--cert-file=/opt/etcd/ssl/server.pem \
--key-file=/opt/etcd/ssl/server-key.pem \
--peer-cert-file=/opt/etcd/ssl/server.pem \
--peer-key-file=/opt/etcd/ssl/server-key.pem \
--trusted-ca-file=/opt/etcd/ssl/etcd-ca.pem \
--peer-trusted-ca-file=/opt/etcd/ssl/etcd-ca.pem \
--logger=zap
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF

拷贝刚才生成的证书 : 把刚才生成的证书拷贝到配置文件中的路径

#将第一步生成的证书文件,拷贝到ssl文件夹下
cp ~/TLS/etcd/*ca*pem ~/TLS/etcd/server*pem /opt/etcd/ssl/

将上面节点 1 所有生成的文件拷贝到master节点 2 和master节点 3 :

for i in k8s-master02 k8s-master03 ;do scp -r /opt/etcd ${i}:/opt ;done
for i in k8s-master02 k8s-master03 ;do scp -r /lib/systemd/system/etcd.service  ${i}:/lib/systemd/system ;done

然后在节点 2 和节点 3 分别修改 etcd.conf 配置文件中的节点名称和当前服务器 IP: 例如

ETCD_NAME="etcd-2"                                             #修改集群唯一标识
ETCD_DATA_DIR="/opt/etcd/data"
ETCD_LISTEN_PEER_URLS="https://192.168.15.216:2380"            #改为本机IP
ETCD_LISTEN_CLIENT_URLS="https://192.168.15.216:2379"          #改为本机IP
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.15.216:2380" #改为本机IP
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.15.216:2379"       #改为本机IP

设置etcd开启自启动,如下命令:

systemctl daemon-reload
systemctl enable etcd  --now    #设置开机自启,并启动

注意:如果etcd集群通讯出现问题,显示已经有用户在使用,此时可以将集群中每个节点的/opt/etcd/data下的member删除,然后重启所有节点即可

查看集群状态,执行命令如下:

ETCDCTL_API=3 /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/etcd-ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.15.215:2379,https://192.168.15.216:2379,https://192.168.15.217:2379" endpoint health --write-out=table

如果输出上面信息,就说明集群部署成功:

如果有问题第一步先看日志:/var/log/message 或 journalctl -u etcd

注意:etcd集群可单独部署在任意机器上,只要能和apiserver通讯即可,etcd备份可参考:k8s之etcd的备份与回恢复 – IT运维 (ywdevops.cn)

二、部署docker:

以下在所有节点操作,这里采用二进制安装,用 yum 安装也一样

1、解压二进制包,并将可执行文件加入到环境变量中,执行命令如下:

tar -zxvf docker-19.03.9.tgz       #解压二进制包
mv docker/*  /usr/bin              #移动到环境变量/usr/bin/目录下

2、由于新版的kubernetes使用systemd来进行资源限制,因此修改docker的CgoupDriver为systemd,执行命令如下:

mkdir /etc/docker

cat > /etc/docker/daemon.json << EOF
{
    "exec-opts": ["native.cgroupdriver=systemd"],
    "max-concurrent-downloads": 10,
    "max-concurrent-uploads": 5,
    "log-driver": "json-file",
    "storage-driver": "overlay2",
    "data-root": "/data/docker",
    "storage-opts": [
    "overlay2.override_kernel_check=true"
    ],
    "log-opts":{
        "max-size": "300m",
        "max-file": "2" 
    },
    "live-restore": true
}
EOF
#live-restore:true 重启docker  不影响运行中的容器
#设置完成后,重启docker

3、通过systemctl 管理docker,执行命令如下:

cat > /usr/lib/systemd/system/docker.service << EOF
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target
[Service]
Type=notify
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target
EOF

3、 启动并设置开机启动 :

systemctl daemon-reload
systemctl start docker
systemctl enable docker

注意:如果docker启动的时候卡死,停止也不行,总之无法启动,可能是selinux没有关闭,k8s1.24之后不在支持dockershim插件,此时可以通过替代品Cri-dockerd实现继续使用docker

三、部署nginx+Keepalived 高可用负载均衡器

注:本例子部署所有组件连接api-server时候直接指定了vip地址,还可以先指定一台机器的api-server地址后,最后统一将配置文件中的机器IP地址和端口替换为vip的地址和端口

1、部署keepalived,可直接通过yum安装或者编译安装,参考链接:部署keepalived

编辑/etc/keealived/keepalived.conf,添加内容如下:

! Configuration File for keepalived

global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    state MASTER                    #注意其余改为BACKUP
    interface ens192
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.15.253/24            #VIP
    }
}

2、编译安装nginx,可参考kubeadm部署章节,链接地址:kubeadm部署k8s

3、执行命令启动keepalived和nginx,如下:

systemctl enable keepalived --now      #添加开机启动并启动
systemctl enable nginx --now

四、部署Master Node:

1、 自签证书颁发机构(CA) :

#进入目录
cd ~/TLS/k8s 
#创建ca文件,注意json的数据格式要对齐
cat > ca-config.json <<EOF
{
 "signing": {
     "default": {
     "expiry": "87600h"
     },
     "profiles": {
       "kubernetes": {
         "expiry": "87600h",
         "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
          ]
      }
    }
  }
}
EOF
cat > ca-csr.json << EOF
{
 "CN": "kubernetes",
 "key": {
     "algo": "rsa",
     "size": 2048
  },
 "names": [
     {
         "C": "CN",
         "L": "Beijing",
         "ST": "Beijing",
         "O": "k8s",
         "OU": "System"
     }
  ]
}
EOF

生成证书, 会生成 ca.pem 和 ca-key.pem 文件 ,执行命令如下:

cfssl gencert -initca ca-csr.json | cfssljson -bare ca -

2、 使用自签 CA 签发 kube-apiserver HTTPS 证书 :

创建证书申请文件:

cat > server-csr.json <<EOF
{
 "CN": "kubernetes",
 "hosts": [
     "10.0.0.1",
     "127.0.0.1",
     "192.168.15.215",
     "192.168.15.216",
     "192.168.15.217",
     "192.168.15.222",
     "192.168.15.223",
     "192.168.15.253",
     "kubernetes",
     "kubernetes.default",
     "kubernetes.default.svc",
     "kubernetes.default.svc.cluster",
     "kubernetes.default.svc.cluster.local"
  ],
 "key": {
     "algo": "rsa",
     "size": 2048
  },
 "names": [
     {
         "C": "CN",
         "L": "BeiJing",
         "ST": "BeiJing",
         "O": "k8s",
         "OU": "System"
     }
  ]
}
EOF
  • 10.0.0.1:serverIP 的首个IP地址
  • 192.168.15.253:VIP
  • 其余IP为apiserverIP,可预留多个

注:上述文件 hosts 字段中 IP 为所有 Master/LB/VIP IP,一个都不能少!为了方 便后期扩容可以多写几个预留的 IP。

生成证书,会生成server.pem和server-key.pem文件,如下命令,

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server

3、从github上下载kubeneter-server的二进制文件,下载地址:

https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md

解压二进制包并拷贝可执行文件,如下:

mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}       #创建文件夹
tar zxvf kubernetes-server-linux-amd64.tar.gz     #解压缩
cd kubernetes/server/bin                          #拷贝包
cp kube-apiserver kube-scheduler kube-controller-manager /opt/kubernetes/bin
cp kubectl /usr/bin/
#将kubectl文件复制到其余两个master节点
for i in k8s-master02 k8s-master03; do scp kubectl ${i}:/usr/bin/ ; done

4、 部署 kube-apiserver :

创建配置文件:

cat > /opt/kubernetes/cfg/kube-apiserver.conf << EOF
KUBE_APISERVER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--etcd-servers=https://192.168.15.215:2379,https://192.168.15.216:2379,https://192.168.15.217:2379 \\
--bind-address=192.168.15.215 \\
--secure-port=6443 \\
--advertise-address=192.168.15.215 \\
--allow-privileged=true \\
--service-cluster-ip-range=10.0.0.0/24 \\
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \\
--authorization-mode=RBAC,Node \\
--enable-bootstrap-token-auth=true \\
--token-auth-file=/opt/kubernetes/cfg/token.csv \\
--service-node-port-range=30000-32767 \\
--kubelet-client-certificate=/opt/kubernetes/ssl/server.pem \\
--kubelet-client-key=/opt/kubernetes/ssl/server-key.pem \\
--tls-cert-file=/opt/kubernetes/ssl/server.pem \\
--tls-private-key-file=/opt/kubernetes/ssl/server-key.pem \\
--client-ca-file=/opt/kubernetes/ssl/ca.pem \\
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \\
--service-account-issuer=https://kubernetes.default.svc.cluster.local \\
--service-account-signing-key-file=/opt/kubernetes/ssl/server-key.pem \\
--etcd-cafile=/opt/etcd/ssl/etcd-ca.pem \\
--etcd-certfile=/opt/etcd/ssl/server.pem \\
--etcd-keyfile=/opt/etcd/ssl/server-key.pem \\
--requestheader-client-ca-file=/opt/kubernetes/ssl/ca.pem \\
--proxy-client-cert-file=/opt/kubernetes/ssl/server.pem \\
--proxy-client-key-file=/opt/kubernetes/ssl/server-key.pem \\
--requestheader-allowed-names=kubernetes \\
--requestheader-extra-headers-prefix=X-Remote-Extra- \\
--requestheader-group-headers=X-Remote-Group \\
--requestheader-username-headers=X-Remote-User \\
--enable-aggregator-routing=true \\
--audit-log-maxage=30 \\
--audit-log-maxbackup=3 \\
--audit-log-maxsize=100 \\
--audit-log-path=/opt/kubernetes/logs/k8s-audit.log"
EOF

注:上面两个\ \ 第一个是转义符,第二个是换行符,使用转义符是为了使用 EOF 保留换行符。

  • –logtostderr:启用日志
  • –v : 日志等级
  • –log-dir:日志目录
  • –etcd-servers:etcd 集群地址
  • –bind-address:监听地址 ,也可以写0.0.0.0
  • –secure-port:https 安全端口
  • –advertise-address:集群通告地址
  • –allow-privileged:启用授权
  • –service-cluster-ip-range:Service 虚拟 IP 地址段
  • –enable-admission-plugins:准入控制模块
  • –authorization-mode:认证授权,启用 RBAC 授权和节点自管理
  • –enable-bootstrap-token-auth:启用 TLS bootstrap 机制
  • –token-auth-file:bootstrap token 文件
  • –service-node-port-range:Service nodeport 类型默认分配端口范围
  • –kubelet-client-xxx:apiserver 访问 kubelet 客户端证书
  • –tls-xxx-file:apiserver https 证书
  • 1.20 版本必须加的参数:–service-account-issuer,–service-accountsigning-key-file
  • –etcd-xxxfile:连接 Etcd 集群证书
  • –audit-log-xxx:审计日志
  • 启动聚合层相关配置:–requestheader-client-ca-file,–proxy-clientcert-file,–proxy-client-key-file,–requestheader-allowed-names,- -requestheader-extra-headers-prefix,–requestheader-group-headers, –requestheader-username-headers,–enable-aggregator-routing(此参数设置为true,metric-server才可采集到数据)

拷贝刚才生成的证书 :

把刚才生成的证书拷贝到配置文件中的路径, 执行命令如下:

cp ~/TLS/k8s/ca*pem ~/TLS/k8s/server*pem /opt/kubernetes/ssl/

启用 TLS Bootstrapping 机制 :

TLS Bootstraping:Master apiserver 启用 TLS 认证后,Node 节点 kubelet 和 kube-proxy 要与 kube-apiserver 进行通信,必须使用 CA 签发的有效证书才可以, 当 Node 节点很多时,这种客户端证书颁发需要大量工作,同样也会增加集群扩展 复杂度。为了简化流程,Kubernetes 引入了 TLS bootstraping 机制来自动颁发客 户端证书,kubelet 会以一个低权限用户自动向 apiserver 申请证书,kubelet 的 证书由 apiserver 动态签署。所以强烈建议在 Node 上使用这种方式,目前主要用 于 kubelet,kube-proxy 还是由我们统一颁发一个证书。

TLS bootstraping 工作流程:

创建上述配置文件中 token 文件:

cat > /opt/kubernetes/cfg/token.csv << EOF
$(head -c 16 /dev/urandom | od -An -t x | tr -d ' '),kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF
#格式:token,用户名,UID,用户组
#token 也可自行生成替换:head -c 16 /dev/urandom | od -An -t x | tr -d ' '
#kubelet-bootstrap用户将作为kubelet首次启动的预设用户,默认情况下没有任何权限,需要给它授权使用此token请求apiserver,包括创建CSR请求

systemd 管理 apiserver :

cat > /usr/lib/systemd/system/kube-apiserver.service << EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=etcd.service
Wants=etcd.service
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-apiserver.conf
ExecStart=/opt/kubernetes/bin/kube-apiserver \$KUBE_APISERVER_OPTS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF

将master节点1的文件拷贝到对应的master节点2和master节点3上面,执行命令如下:

for i in k8s-master02 k8s-master03;do scp -r /opt/kubernetes ${i}:/opt ;done
for i in k8s-master02 k8s-master03;do scp /lib/systemd/system/kube-apiserver.service  ${i}:/lib/systemd/system  ;done

注:拷贝过去之后记得要修改节点2和节点的kube-apiserver.conf文件中IP地址为本机的IP地址,否则apiserver启动会失败

启动并设置开机启动

systemctl daemon-reload
systemctl enable kube-apiserver --now
1、启动日志输出:kube-apiserver[7509]: E0715 10:38:57.686241    7509 instance.go:392] Could not construct pre-rendered responses for ServiceAccountIss..., got: api
Hint: Some lines were ellipsized, use -l to show in full.
解决:查看kube-apiserver.conf中的server-account-issuer配置,修改为https://kubernetes.default.svc.cluster.local
2、Unable to remove old endpoints from kubernetes service: StorageError: key not found, Code: 1, Key: /registry/masterleases/10.88.15.215, ResourceVersion: 0, AdditionalErrorMsg:  
解决:此错误无影响
3、etcd提示:leader failed to send out heartbeat on time; took too long, leader is overloaded likely from slow disk,
解决:此内容并非错误,只是提示数据写入etcd时间长,不影响apiserver使用,将etcd磁盘换成ssd即可

注:3个master节点都部署了apiserver+controller-manager+scheduler,kube-controller-manager、kube-scheduler是连接本机的kube-apiserver,可以把它们看做一个整体,只要有一个节点的apiserver实例正常,就可以保证集群apiserver可用,最外层通过haproxy/nginx做负载

5、 部署 kube-controller-manager(master1节点执行) :

创建配置文件 : (三台master机器都要执行,可copy过去)

cat > /opt/kubernetes/cfg/kube-controller-manager.conf << EOF
KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--leader-elect=true \\
--kubeconfig=/opt/kubernetes/cfg/kube-controller-manager.kubeconfig \\
--bind-address=127.0.0.1 \\
--allocate-node-cidrs=true \\
--cluster-cidr=10.244.0.0/16 \\
--service-cluster-ip-range=10.0.0.0/24 \\
--cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pem \\
--cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem \\
--root-ca-file=/opt/kubernetes/ssl/ca.pem \\
--service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem \\
--cluster-signing-duration=87600h0m0s"
EOF
  • –kubeconfig:连接 apiserver 配置文件
  • –leader-elect:当该组件启动多个时,自动选举(HA)
  • –cluster-signing-cert-file/–cluster-signing-key-file:自动为 kubelet 颁发证书的 CA,与 apiserver 保持一致
  • –cluster-cidr: pod网段地址
#将配置文件copy到其余机器上
for i in k8s-master02 k8s-master03 ;do scp /opt/kubernetes/cfg/kube-controller-manager.conf ${i}:/opt/kubernetes/cfg ;done

生成 kube-controller-manager 证书: (可将证书拷贝到其余节点)

# 切换工作目录
cd ~/TLS/k8s
# 创建证书请求文件
cat > kube-controller-manager-csr.json << EOF
{
    "CN": "system:kube-controller-manager",
    "hosts": [],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "BeiJing",
            "L": "BeiJing",
            "O": "system:masters",
            "OU": "System"
        }
    ]
}
EOF

生成证书,会生成两个pem文件 :

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager
#将生成的证书文件复制到本机的/opt/kubernetes/ssl
cp kube-controller-manager.pem kube-controller-manager-key.pem /opt/kubernetes/ssl/
#将证书文件复制到其余master节点
for i in k8s-master02 k8s-master03;do scp /opt/kubernetes/ssl/{kube-controller-manager.pem, kube-controller-manager-key.pem} ${i}:/opt/kubernetes/ssl/ ;done

生成 kubeconfig 文件,用于连接apiserver:

KUBE_CONFIG="/opt/kubernetes/cfg/kube-controller-manager.kubeconfig"
KUBE_APISERVER="https://192.168.15.253:16443"
#注意要在证书所在路径执行,否则提示找不到证书文件
kubectl config set-cluster kubernetes \
 --certificate-authority=/opt/kubernetes/ssl/ca.pem \
 --embed-certs=true \
 --server=${KUBE_APISERVER} \
 --kubeconfig=${KUBE_CONFIG}
kubectl config set-credentials kube-controller-manager \
 --client-certificate=./kube-controller-manager.pem \
 --client-key=./kube-controller-manager-key.pem \
 --embed-certs=true \
 --kubeconfig=${KUBE_CONFIG}
kubectl config set-context default \
 --cluster=kubernetes \
 --user=kube-controller-manager \
 --kubeconfig=${KUBE_CONFIG}
kubectl config use-context default --kubeconfig=${KUBE_CONFIG}

systemd 管理 controller-manager :

cat > /usr/lib/systemd/system/kube-controller-manager.service << EOF
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-controller-manager.conf
ExecStart=/opt/kubernetes/bin/kube-controller-manager \$KUBE_CONTROLLER_MANAGER_OPTS
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF

将服务启动配置文件和kubeconfig文件copy到其他master节点机器上,执行命令如下:

for i in k8s-master02 k8s-master03;do scp /lib/systemd/system/kube-controller-manager.service ${i}:/lib/systemd/system;done
for i in k8s-master02 k8s-master03;do scp /opt/kubernetes/cfg/kube-controller-manager.kubeconfig ${i}:/opt/kubernetes/cfg/;done

启动并设置开机启动:

systemctl daemon-reload
systemctl enable kube-controller-manager --now

启动后查看日志是否有报错,无报错即表示没问题

#如下错误可忽略
Failed to start service controller: WARNING: no cloud provider provided, services of type LoadBalancer will fail

6、 部署 kube-scheduler :(三台master都要部署)

创建配置文件 :

cat > /opt/kubernetes/cfg/kube-scheduler.conf << EOF
KUBE_SCHEDULER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--leader-elect \\
--kubeconfig=/opt/kubernetes/cfg/kube-scheduler.kubeconfig \\
--bind-address=127.0.0.1"
EOF
  • –kubeconfig:连接 apiserver 配置文件
  • –leader-elect:当该组件启动多个时,自动选举(HA)
#将配置文件发送到其余master节点
for i in k8s-master02 k8s-master03 ;do scp /opt/kubernetes/cfg/kube-scheduler.conf ${i}:/opt/kubernetes/cfg/ ; done

生成 kube-scheduler 证书请求文件CSR:

# 切换工作目录
cd ~/TLS/k8s
#创建证书请求文件
cat > kube-scheduler-csr.json << EOF
{
 "CN": "system:kube-scheduler",
 "hosts": [],
 "key": {
     "algo": "rsa",
     "size": 2048
  },
 "names": [
   {
      "C": "CN",
      "L": "BeiJing",
      "ST": "BeiJing",
      "O": "system:masters",
      "OU": "System"
   }
  ]
}
EOF

生成证书,名称为kube-scheduler-key.pem和kube-scheduler.pem,命令如下:

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-scheduler-csr.json | cfssljson -bare kube-scheduler
#先将证书文件copy到本机的/opt/kubernetes/ssl
cp kube-scheduler-key.pem kube-scheduler.pem  /opt/kubernetes/ssl
#再将证书copy导其余的master节点上
for i in k8s-master02 k8s-master03;do scp /opt/kubernetes/ssl/{kube-scheduler-key.pem,kube-scheduler.pem} ${i}:/opt/kubernetes/ssl/ ;done

生成 kubeconfig 文件,用于连接apiserver:

KUBE_CONFIG="/opt/kubernetes/cfg/kube-scheduler.kubeconfig"
KUBE_APISERVER="https://192.168.15.253:16443"
#下面步骤需要进入/opt/kubernetes/ssl目录执行
kubectl config set-cluster kubernetes \
 --certificate-authority=/opt/kubernetes/ssl/ca.pem \
 --embed-certs=true \
 --server=${KUBE_APISERVER} \
 --kubeconfig=${KUBE_CONFIG}
kubectl config set-credentials kube-scheduler \
 --client-certificate=./kube-scheduler.pem \
 --client-key=./kube-scheduler-key.pem \
 --embed-certs=true \
 --kubeconfig=${KUBE_CONFIG}
kubectl config set-context default \
 --cluster=kubernetes \
 --user=kube-scheduler \
 --kubeconfig=${KUBE_CONFIG}
kubectl config use-context default --kubeconfig=${KUBE_CONFIG}

systemd 管理 scheduler :

cat > /usr/lib/systemd/system/kube-scheduler.service << EOF
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-scheduler.conf
ExecStart=/opt/kubernetes/bin/kube-scheduler \$KUBE_SCHEDULER_OPTS
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
#服务配置文件和kubeconfig文件copy到其余两个master节点上
for i in k8s-master02 k8s-master03;do scp /lib/systemd/system/kube-scheduler.service ${i}:/lib/systemd/system ;done
for i in k8s-master02 k8s-master03;do scp /opt/kubernetes/cfg/kube-scheduler.kubeconfig ${i}:/opt/kubernetes/cfg/ ;done

启动并设置开机启动 :

systemctl daemon-reload
systemctl start kube-scheduler
systemctl enable kube-scheduler

7、 查看集群状态 :

注意:此步骤可以单独部署集群之外的机器上

生成 kubectl 连接集群的证书:

# 切换工作目录
cd ~/TLS/k8s
cat >  admin-csr.json << EOF
{
 "CN": "admin",
 "hosts": [],
 "key": {
     "algo": "rsa",
     "size": 2048
 },
 "names": [
   {
     "C": "CN",
     "L": "BeiJing",
     "ST": "BeiJing",
     "O": "system:masters",
     "OU": "System"
   }
 ]
}
EOF

生成证书:

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin

复制证书文件到/opt/kubernetes/ssl中

 cp admin-key.pem admin.pem /opt/kubernetes/ssl/

生成 kubeconfig 文件:

#创建文件夹.kube
mkdir /root/.kube
KUBE_CONFIG="/root/.kube/config"
KUBE_APISERVER="https://192.168.15.253:16443"  #注意:此地址为VIP地址,防止单点apiserver挂掉
cd /opt/kubernetes/ssl
kubectl config set-cluster kubernetes \
 --certificate-authority=/opt/kubernetes/ssl/ca.pem \
 --embed-certs=true \
 --server=${KUBE_APISERVER} \
 --kubeconfig=${KUBE_CONFIG}
kubectl config set-credentials cluster-admin \
 --client-certificate=./admin.pem \
 --client-key=./admin-key.pem \
 --embed-certs=true \
 --kubeconfig=${KUBE_CONFIG}
kubectl config set-context default \
 --cluster=kubernetes \
 --user=cluster-admin \
 --kubeconfig=${KUBE_CONFIG}
kubectl config use-context default --kubeconfig=${KUBE_CONFIG}

通过 kubectl 工具查看当前集群组件状态,输出如下表示各组件正常,如图:

注意:此步骤可以不部署在任何一个节点上,可以单独部署一个机器用来管理集群,在生成 kubeconfig 文件时kube-apiserver 地址要写vip地址(防止其中某个节点Down)

配置kubectl命令补全:

yum install -y bash-completion
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
kubectl completion bash > ~/.kube/completion.bash.inc
source '/root/.kube/completion.bash.inc'
source $HOME/.bash_profile

8、授权kubelet-bootstrap用户允许请求证书:

kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap
#在默认情况下,kubelet 通过 bootstrap.kubeconfig 中的预设用户 Token 声明了自己的身份,然后创建 CSR 请求,但是默认情况下此用户没任何权限的,包括创建 CSR 请求;所以需要如下命令创建一个 ClusterRoleBinding,将预设用户 kubelet-bootstrap 与内置的 ClusterRole system:node-bootstrapper 绑定到一起,使其能够发起 CSR 请求

五、 部署Node:

在master1节点执行,因为master节点也部署kubelet和proxy

#解压kubernetes-server-linux-amd64.tar.gz
tar -zxvf kubernetes-server-linux-amd64.tar.gz
cd kubernetes/server/bin
#copy到本地的/opt/kubernetes/bin路径下
cp kubelet kube-proxy /opt/kubernetes/bin
在node节点创建路径和文件夹
for i in k8s-node01 k8s-node02;do ssh ${i} mkdir -p /opt/kubernetes/{cfg,logs,bin,ssl} ;done
#将kubelet、kube-proxy拷贝到其余的master节点和node节点
for i in k8s-master02 k8s-master03 k8s-node01 k8s-node02;do scp /opt/kubernetes/bin/{kubelet, kube-proxy} ${i}:/opt/kubernetes/bin/ ;done
#将ca.pem、ca-key.pem文件拷贝到其余的node节点上
for i in k8s-node01 k8s-node02;do scp /opt/kubernetes/ssl/{ca.pem,ca-key.pem} ${i}:/opt/kubernetes/ssl/ ;done

注意:kubelet启动的时候需要ca.pem和ca-key.pem,没有这两个文件启动会报错

部署 kubelet (只在master1执行):

1、 创建配置文件 :

#导入pause镜像,执行命令docker load -i pause-amd64:3.3或者从阿里云下载:
docker pull registry.aliyuncs.com/google_containers/pause-amd64:3.3
#创建文件
cat > /opt/kubernetes/cfg/kubelet.conf << EOF
KUBELET_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--hostname-override=k8s-master1 \\
--network-plugin=cni \\
--kubeconfig=/opt/kubernetes/cfg/kubelet.kubeconfig \\
--bootstrap-kubeconfig=/opt/kubernetes/cfg/bootstrap.kubeconfig \\
--config=/opt/kubernetes/cfg/kubelet-config.yml \\
--cert-dir=/opt/kubernetes/ssl \\
--pod-infra-container-image=registry.aliyuncs.com/google_containers/pause-amd64:3.3"
EOF
  • 注意更改hostname-override名字
cat > /opt/kubernetes/cfg/kubelet-config.yml << EOF
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: 0.0.0.0
port: 10250
readOnlyPort: 10255
cgroupDriver: systemd      #注意,驱动要和/etc/docker/daemon.json中一致
clusterDNS:
- 10.0.0.10
clusterDomain: cluster.local
failSwapOn: false
authentication:
 anonymous:
   enabled: false
 webhook:
   cacheTTL: 2m0s
   enabled: true
 x509:
   clientCAFile: /opt/kubernetes/ssl/ca.pem
authorization:
 mode: Webhook
 webhook:
   cacheAuthorizedTTL: 5m0s
   cacheUnauthorizedTTL: 30s
evictionHard:
 imagefs.available: 15%
 memory.available: 100Mi
 nodefs.available: 10%
 nodefs.inodesFree: 5%
maxOpenFiles: 1000000
maxPods: 110
EOF
  • clusterDNS:集群DNS地址,一般为server ip的第十个IP地址

3、 生成 kubelet 初次加入集群引导 kubeconfig 文件 :

KUBE_CONFIG="/opt/kubernetes/cfg/bootstrap.kubeconfig"

KUBE_APISERVER="https://192.168.15.253:16443"   #注意:连接的是VIP

TOKEN=$(awk -F "," '{print $1}' /opt/kubernetes/cfg/token.csv)       # 与 token.csv 里保持一致

# 生成 kubelet bootstrap kubeconfig 配置文件,注意,需要先将master节点的/opt/kubernetes/ssl下的证书文件拷贝到worker节点中

kubectl config set-cluster kubernetes \
 --certificate-authority=/opt/kubernetes/ssl/ca.pem \
 --embed-certs=true \
 --server=${KUBE_APISERVER} \
 --kubeconfig=${KUBE_CONFIG}
kubectl config set-credentials "kubelet-bootstrap" \
 --token=${TOKEN} \
 --kubeconfig=${KUBE_CONFIG}
kubectl config set-context default \
 --cluster=kubernetes \
 --user="kubelet-bootstrap" \
 --kubeconfig=${KUBE_CONFIG}
kubectl config use-context default --kubeconfig=${KUBE_CONFIG}

4、 systemd 管理 kubelet :

cat > /usr/lib/systemd/system/kubelet.service << EOF
[Unit]
Description=Kubernetes Kubelet
After=docker.service
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kubelet.conf
ExecStart=/opt/kubernetes/bin/kubelet \$KUBELET_OPTS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF

5、将master1节点的kubelet相关组件发送到其他master和worker节点,举例如下:

for i in  k8s-master02 k8s-master03 k8s-node01 k8s-node02;do scp /opt/kubernetes/cfg/{kubelet.conf,kubelet-config.yml,bootstrap.kubeconfig} ${i}:/opt/kubernetes/cfg/ ;done
for i in  k8s-master02 k8s-master03 k8s-node01 k8s-node02;do scp /lib/systemd/system/kubelet.service ${i}:/lib/systemd/system ;done

注意: 目标机器上记得修改kubelet.conf中的hostname-override的

6、 启动并设置开机启动(所有节点) :

systemctl daemon-reload
systemctl start kubelet
systemctl enable kubelet

批准节点加入集群

1、手动方式批准:

在 kubelet 首次启动后,如果用户 Token 没问题,并且 RBAC 也做了相应的设置,那么此时在集群内应该能看到 kubelet 发起的 CSR 请求,如图:

在master节点执行,也可在单独的用于连接集群的机器上执行如下命令

# 批准加入集群
kubectl certificate approve  node-csr-8CrwSP6Rpx7sxwa3T_DNl5AEyLEWuowxbruOasn6nYA

查看节点信息,如图:

注:由于网络插件还没有部署,节点会没有准备就绪 NotReady

注意:如果删除了节点,需要删除之前的csr请求,找到节点的/opt/kubernetes/ssl与/opt/kubernetes/cfg目录,删除如下几个文件和kubelet.kubeconfig文件:

删除后,重启kubelet,即可在master节点重新看到Pending请求

可通过如下命令查看csr属于哪个节点,并执行删除操作:

kubectl describe csr node-csr-7reKUW9KL3Ec70E6xvE834I_-BgyyH7Glx7wTTUC04s
kubectl delete csr node-csr-7reKUW9KL3Ec70E6xvE834I_-BgyyH7Glx7wTTUC04s

2、自动方式批准:

参考:kubelet初始化过程

部署 kube-proxy (只在master1执行):

1、 创建配置文件 :

cat > /opt/kubernetes/cfg/kube-proxy.conf << EOF
KUBE_PROXY_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--config=/opt/kubernetes/cfg/kube-proxy-config.yml"
EOF

2、 配置参数文件 :

cat > /opt/kubernetes/cfg/kube-proxy-config.yml << EOF
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0
metricsBindAddress: 0.0.0.0:10249
clientConnection:
  kubeconfig: /opt/kubernetes/cfg/kube-proxy.kubeconfig
hostnameOverride: k8s-master1
clusterCIDR: 10.244.0.0/16
mode: "ipvs"
EOF

3、 生成 kube-proxy.kubeconfig 文件 :

# 切换工作目录
cd ~/TLS/k8s
#创建证书请求文件
cat > kube-proxy-csr.json << EOF
{
 "CN": "system:kube-proxy",
 "hosts": [],
 "key": {
     "algo": "rsa",
     "size": 2048
 },
 "names": [
   {
     "C": "CN",
     "L": "BeiJing",
     "ST": "BeiJing",
     "O": "k8s",
     "OU": "System"
   }
 ]
}
EOF

生成证书:

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy

生成 kubeconfig 文件:

KUBE_CONFIG="/opt/kubernetes/cfg/kube-proxy.kubeconfig"
KUBE_APISERVER="https://192.168.15.253:16443"       #注意:此位置为VIP
kubectl config set-cluster kubernetes \
 --certificate-authority=/opt/kubernetes/ssl/ca.pem \
 --embed-certs=true \
 --server=${KUBE_APISERVER} \
 --kubeconfig=${KUBE_CONFIG}
kubectl config set-credentials kube-proxy \
 --client-certificate=./kube-proxy.pem \
 --client-key=./kube-proxy-key.pem \
 --embed-certs=true \
 --kubeconfig=${KUBE_CONFIG}
kubectl config set-context default \
 --cluster=kubernetes \
 --user=kube-proxy \
 --kubeconfig=${KUBE_CONFIG}
kubectl config use-context default --kubeconfig=${KUBE_CONFIG}

4、 systemd 管理 kube-proxy

cat > /usr/lib/systemd/system/kube-proxy.service << EOF
[Unit]
Description=Kubernetes Proxy
After=network.target
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-proxy.conf
ExecStart=/opt/kubernetes/bin/kube-proxy \$KUBE_PROXY_OPTS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF

5、将master1节点上的kube-proxy相关文件发送到master和worker节点中,举例如下:

for i in k8s-master02 k8s-master03 k8s-node01 k8s-node02;do scp kube-proxy.conf kube-proxy-config.yml kube-proxy.kubeconfig ${i}:/opt/kubernetes/cfg/ ;done
for i in k8s-master02 k8s-master03 k8s-node01 k8s-node02;do scp /lib/systemd/system/kube-proxy.service  ${i}:/lib/systemd/system ;done

注意:要修改kube-proxy-config.yml中的hostnameOverride的值

6、 启动并设置开机启动(全部节点) :

systemctl daemon-reload
systemctl start kube-proxy
systemctl enable kube-proxy

注:如果pod无法ping通svc的IP地址,可能是kube-proxy模式问题,修改为ipvs即可,查看当前模式命令:curl 127.0.0.1:10249/proxyMode

六、部署网络组件 :

Calico 是一个纯三层的数据中心网络方案,是目前 Kubernetes 主流的网络方案。

Calico以DaemonSet方式运行在集群的每个节点上,当扩容node节点后,新节点会自动运行calico的Pod

下载地址:https://projectcalico.docs.tigera.io/getting-started/kubernetes/self-managed-onprem/onpremises
下载命令:curl https://projectcalico.docs.tigera.io/manifests/calico.yaml -O

1、首先下载calico.yaml文件,编辑文件,修改镜像地址为内部的harbor地址(两个cni地址、一个flexvol地址、一个node地址、一个controllers地址),如图:

2、创建密钥认证文件(集群master1节点创建即可,其余连接到集群的都可以使用)

#首先编辑docker文件,添加仓库地址,执行命令如下:
vim   /etc/docker/daemon.json
#添加内容如下:
"insecure-registries":["192.168.26.131"]
#重启docker
systemctl restart docker
#登录harbor
docker login 192.168.26.131
#进入root/.docker目录下,执行命令生成密钥
cat config.json | base64     #可以得到一串字符串
#编辑文件secret.yaml添加内容如下,其中.dockerconfigjson位置填写上一步生成的加密字符串,namespace指定命名空间,name用于指定名字,可自定义,其余都按照下图写即可
apiVersion: v1
kind: Secret
metadata:
    name: secret-key
    namespace: kube-system
data:
    .dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxMC44OC4yNi4xMzEiOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVPSIKCQl9Cgl9LAoJIkh0dHBIZWFkZXJzIjogewoJCSJVc2VyLUFnZW50IjogIkRvY2tlci1DbGllbnQvMTkuMDMuOSAobGludXgpIgoJfQp9
type: kubernetes.io/dockerconfigjson
#配置完成后,执行命令创建密钥认证
kubectl create -f secret.yaml 
#执行命令查看,要执行命名空间,如下:
kubectl get secret -n kube-system

3、在calico.yaml中配置密钥认证文件,一共两个位置需要配

第一个位置是DaemonSet控制器位置,也就是cni容器上方,如图:

第二个是Deployment控制器位置,也就是controllers容器上方,如图:

注:在执行下面的apply命令之前确保所有节点都可以登录到仓库中,docker login 仓库地址

4、配置完成后执行命令创建calico网络组件,如下:

kubectl apply -f calico.yaml

5、通过如下命令查看calico是否创建成功,记得执行命名空间,如图:

从上图可以看出,状态都是running,表示成功,此时再次执行kubectl get node 可以看到已经显示Ready,如图:

注意:如果不改变其他配置,calico默认采用IPIP网络模式

calico配置文件,适用于1.20.8版本的kubernetes,参考:calico清单文件

授权 apiserver 访问 kubelet :

在master节点执行命令如下:

cat > apiserver-tokkubelet-rbac.yaml <<EOF
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
     - pods/log
   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: kubernetes
EOF

执行如下命令创建授权:

kubectl apply -f apiserver-to-kubelet-rbac.yaml

注意:如果不授权,那么通过kubectl logs查看日志会提示错误如下:

Error from server (Forbidden): Forbidden (user=kubernetes, verb=get, resource=nodes, subresource=proxy) ( pods/log calico-node-kg9pc)

部署 CoreDNS

CoreDNS 用于集群内部 Service 名称解析

执行如下命令运行coredns,如下:

kubectl apply -f coredns.yaml 

查看是否创建成功,如图:

coredns内容参考:coredns清单文件

说明:

  • 注意clusterIP的地址,要与kubelet配置文件中的clusterdns地址一致

集群可用性验证

  • pod必须可以解析service
  • pod必须可以解析跨namspace的service
  • 每个节点都必须能访问kubernetes的service(443端口)和kube-dns的service(53端口)
  • Pod和pod之间要能通(同namespace、跨namespace、跨机器能通)

1、创建busybox的pod,在内部验证解析service和跨namespace的service,如图:

注:busybox版本可用1.28.3,最新版本可能出现解析有问题

2、验证所有节点访问kubernetes的service(443端口)和kube-dns的service(53端口),如图:

3、pod与pod之间通信验证,登录进入pod内部,ping其余Pod的IP即可

metricsever部署

参考链接:metric-server部署

posted @ 2023-02-22 15:54  技术颜良  阅读(755)  评论(1编辑  收藏  举报