目录

1、安装要求

2、安装规划

3.1、分步骤操作

3.2、一键执行脚本

4.1、安装cfssl证书生成工具

4.2、创建认证中心(根CA中心)

4.3、使用自签CA签发Etcd证书

4.4、部署Etcd集群

5、部署Docker

6.1、创建认证中心(根CA中心)

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

6.3、部署kube-apiserver组件

6.4、部署kube-controller-manager

6.5、部署kube-scheduler

6.6、查看集群状态

7.1、拷贝二进制文件至node0节点

7.2、部署kubelet服务

7.3、批准kubelet证书申请并加入集群

7.4、部署kube-proxy服务

7.5、授权apiserver访问kubelet

7.6、部署Flannel网络插件

7.7、部署CoreDNS解析插件

8、继续增加Work Node

8.1、部署第二个node节点

8.2、部署第三个node节点

10、安装dashboard

10.1、创建dashboard

10.2、cluster-admin管理员角色绑定


1、安装要求

在开始之前,部署Kubernetes集群机器需要满足以下几个条件:

  • 三台机器,操作系统 CentOS7.7(mini)

  • 硬件配置:2GBRAM,2vCPU+,硬盘30GB+

  • 集群中所有机器之间网络互通,且可访问外网

  • 采用NAT网络模型(依自己情况而定)

2、安装规划

(1)服务器规划

角色 IP
master 192.168.50.128
node0 192.168.50.128
node1 192.168.50.131
node2 192.168.50.132

(2)软件环境

软件 版本
Docker 19.03.12
kubernetes 1.18.6
etcd 3.4.9

(3)软件规划

主机 安装组件
master kube-apiserver,kube-controller-manager,kube-scheduler,etcd
node1 kubelet,kube-proxy,etcd
node2 kubelet,kube-proxy,etcd

3、初始化系统

3.1、分步骤操作

(1)配置主机名

master节点设置:

~]# hostnamectl set-hostname master

node1从节点设置:

~]# hostnamectl set-hostname node1

node2从节点设置:

~]# hostnamectl set-hostname node2

根据自己的节点命名情况来设置即可。

(2)添加hosts

所有的节点都要添加hosts解析记录

~]# cat >>/etc/hosts <<EOF
192.168.50.128 master
192.168.50.128 node0
192.168.50.131 node1
192.168.50.132 node2
EOF

(3)配置免密

在master1节点生成密钥对,并分发给其他的所有主机。

[root@master ~]# ssh-keygen -t rsa -b 1200
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:OoMw1dARsWhbJKAQL2hUxwnM4tLQJeLynAQHzqNQs5s root@localhost.localdomain
The key's randomart image is:
+---[RSA 1200]----+
|*=X=*o*+         |
|OO.*.O..         |
|BO= + +          |
|**o* o           |
|o E .   S        |
|   o . .         |
|    . +          |
|       o         |
|                 |
+----[SHA256]-----+
  • 分发公钥

[root@master ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub  root@master
[root@master ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub  root@node1
[root@master ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub  root@node2

(4)升级内核(建议)

通过下载kernel image的rpm包进行安装。

centos7:http://elrepo.org/linux/kernel/el7/x86_64/RPMS/

编写shell脚本升级内核

#!/bin/bash
# ----------------------------
# upgrade kernel by bomingit@126.com
# ----------------------------yum localinstall -y kernel-lt*
if [ $? -eq 0 ];thengrub2-set-default 0 && grub2-mkconfig -o /etc/grub2.cfggrubby --args="user_namespace.enable=1" --update-kernel="$(grubby --default-kernel)"
fi
echo "please reboot your system quick!!!"

注意:一定要重启机器

  • 验证内核版本

[root@master1 ~]# uname -r
4.4.229-1.el7.elrepo.x86_64

(5)关闭防火墙、selinux

~]# systemctl disable --now firewalld
~]# setenforce 0
~]# sed -i 's/enforcing/disabled/' /etc/selinux/config

(6)关闭swap分区

~]# swapoff -a
~]# sed -i.bak 's/^.*centos-swap/#&/g' /etc/fstab

第一条是临时关闭,当然也可以使用第二条永久关闭,后者手动在/etc/fstab文件中将swap挂载所在的行注释掉即可。

(7)优化内核

~]# cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward=1
vm.swappiness=0
EOF

使其立即生效

~]# sysctl --system

(8)时区和时间同步

~]# ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
~]# yum install dnf -y
~]# dnf makecache
~]# dnf install ntpdate -y
~]# ntpdate ntp.aliyun.com

(9)配置yum源

所有的节点均采用阿里云官网的base和epel源

~]# curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
~]# curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

3.2、一键执行脚本

(1)编写shell

将上面的第5-8步骤写成shell脚本自动化快速完成

#!/bin/sh
#****************************************************************#
# ScriptName: init.sh
# Author: boming
# Create Date: 2020-06-23 22:19
#***************************************************************##关闭防火墙
systemctl disable --now firewalld
setenforce 0
sed -i 's/enforcing/disabled/' /etc/selinux/config
#关闭swap分区
swapoff -a
sed -i.bak 's/^.*centos-swap/#&/g' /etc/fstab
#优化系统
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
#立即生效
sysctl --system
#时区
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
#配置阿里云的base和epel源
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
#安装dnf工具
yum install dnf -y
dnf makecache
#安装ntpdate工具
dnf install ntpdate -y
#同步阿里云时间
ntpdate ntp.aliyun.com

在其他的节点执行此脚本跑一下即可。
4、部署Etcd集群

Etcd 是一个分布式键值存储系统,Kubernetes使用Etcd进行状态和数据存储,因此我们需要提前准备好Etcd,不过为解决Etcd单点故障问题,应采用集群方式部署,这里使用3台组建集群。

为了节约资源利用,我这里复用了两个node节点,这样子这三台主机便可组建一个集群。当然,建议是独立于k8s集群之外部署,毕竟数据很重要。

Etcd节点名称 IP
etcd-01 192.168.50.128
etcd-02 192.168.50.131
etcd-03 192.168.50.132

4.1、安装cfssl证书生成工具

在kubernetes中,使用openssl生成证书会及其麻烦,如果我们可以把预先的证书机构、使用期等时间写在json文件里面会更加高效和自动化。而cfssl就是这样的一款工具,cfssl采用go语言编写,是一个开源的证书管理工具,cfssljson用来从cfssl程序获取json输出,并将证书,密钥,csr和bundle写入文件中。

在master节点操作:

[root@master ~]# wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
[root@master ~]# wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
[root@master ~]# ls
cfssljson_linux-amd64  cfssl_linux-amd64

授权并重命名:

[root@master ~]# chmod +x cfssljson_linux-amd64
[root@master ~]# chmod +x cfssl_linux-amd64
[root@master ~]# mv cfssljson_linux-amd64 cfssljson
[root@master ~]# mv cfssl_linux-amd64 cfssl
[root@master ~]# ll
total 12364
-rwxr-xr-x 1 root root 10376657 Mar 29  2016 cfssl
-rwxr-xr-x 1 root root  2277873 Mar 29  2016 cfssljson

移动到环境变量/usr/local/bin目录下

[root@master ~]# mv cfssljson cfssl /usr/local/bin

4.2、创建认证中心(根CA中心)

由于kubernetes各组件需要使用x509证书对通信进行加密和认证,所以需要创建一套CA(Certificate Autority),是自签名的根证书,用来签名后续需要创建的其它证书;

这里创建的CA是一个私有的内部认证中心,这个认证中心也需要一个CA证书和相应的CA私钥,CA私钥需要妥善保管,任何拥有它的人,都可以充当CA颁发证书。

(1)创建请求证书的json配置文件

再次强调一下,CA证书的请求json文件是集群所有节点共享的,只需要创建一个,它后续创建的所有其它子CA证书的基础,子CA证书都会根据这里config中的profile段来生成证书的相关信息;

[root@master ~]# mkdir -pv ~/TLS/etcd && cd ~/TLS/etcd
[root@master etcd]# cat > ca-config.json << EOF
{"signing": {"default": {"expiry": "87600h"},"profiles": {"www": {"expiry": "87600h","usages": ["signing","key encipherment","server auth","client auth"]}}}
}
EOF

ca-config.json 这个配置文件只是告诉我们颁发有什么功能的证书,它用于配置证书的使用场景(profile)和具体参数(usage、过期时间、服务端认证、客户端认证、加密等)。

default是默认策略,指定证书默认有效期是10年;

profiles是定义使用场景,这里只是kubernetes,其实可以定义多个场景,分别指定不同的过期时间,使用场景等参数,后续签名证书时使用某个profile;

signing: 表示该证书可用于签名其它证书,生成的ca.pem证书中的CA=TRUE;

server auth: 表示client 可以用该CA 对server 提供的证书进行校验;

client auth: 表示server 可以用该CA 对client 提供的证书进行验证。

(2)创建根CA证书签名请求文件

[root@master etcd]# cat > ca-csr.json << EOF
{"CN": "etcd CA","key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "Beijing","ST": "Beijing"}]
}
EOF

(3)生成证书

[root@master etcd]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
[root@master etcd]# ls -l ca*pem
-rw------- 1 root root 1679 Jul 14 10:08 ca-key.pem
-rw-r--r-- 1 root root 1359 Jul 14 10:08 ca.pem

gencert:生成新的key(密钥)和签名证书

--initca:初始化一个新ca

4.3、使用自签CA签发Etcd证书

(1)创建Etcd证书签名请求文件

[root@master etcd]# cat > server-csr.json << EOF
{"CN": "etcd","hosts": ["192.168.50.128","192.168.50.131","192.168.50.132"],"key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "BeiJing","ST": "BeiJing"}]
}
EOF

hosts字段中IP为所有etcd节点的集群内部通信IP,有几个etcd节点,就写多少个IP。当然,为方便后期扩容可以多些几个预留的IP。

(2)生成证书

[root@master etcd]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server
[root@master etcd]# ls -l server*.pem
-rw------- 1 root root 1679 Jul 14 10:18 server-key.pem
-rw-r--r-- 1 root root 1383 Jul 14 10:18 server.pem

gencert: 生成新的key(密钥)和签名证书-initca:初始化一个新ca-ca:指明ca的证书-ca-key:指明ca的私钥文件 -config:指明请求证书的json文件-profile:与config中的profile对应,是指根据config中的profile段来生成证书的相关信息

(3)证书分发至其他etcd服务器

将前面两步创建的证书都分发给其他etcd节点。

写一个shell脚本,先在目标主机创建存放etcd证书的目录,接着复制证书

#!/bin/bashfor node in master node1 node2
dossh root@${node} "mkdir -pv /etc/etcd/ssl"scp ~/TLS/etcd/ca*.pem  root@${node}:/etc/etcd/sslscp ~/TLS/etcd/server*.pem  root@${node}:/etc/etcd/ssl
done

补充:事实上只需要分发ca.pem公钥即可,ca-key.pem是私钥,很多组件不需要,除非你确保使用它,你才分发到服务器上面,以免造成私钥泄露。不过我们不需要考虑太多,所以把私钥也分发到了服务器上面。

4.4、部署Etcd集群

以下在节点1操作,部署完成后,将节点1生成的所有的文件拷贝到节点2和节点3

(1)解压Etcd包并拷贝二进制执行程序

[root@master etcd]# cd
[root@master ~]# tar xf etcd-v3.4.9-linux-amd64.tar.gz
[root@master ~]# cp -a etcd-v3.4.9-linux-amd64/{etcd,etcdctl} /usr/local/bin

(2)创建Etcd配置文件

[root@master ~]# mkdir -pv /etc/etcd/cfg
[root@master ~]# cat >/etc/etcd/cfg/etcd.conf <<EOF
#[Member]
ETCD_NAME="etcd-01"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.50.128:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.50.128:2379,http://127.0.0.1:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.50.128:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.50.128:2379"
ETCD_INITIAL_CLUSTER="etcd-01=https://192.168.50.128:2380,etcd-02=https://192.168.50.131:2380,etcd-03=https://192.168.50.132:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
EOF

这里解释一下配置

配置选项 选项说明
ETCD_NAME 节点名称,如果ETCD_INITIAL_CLUSTER_STATE="new"这个值为new,哪么ETCD_NAME的参数值必须位于ETCD_INITIAL_CLUSTER列表中
ETCD_DATA_DIR 指定节点的数据存储目录(包括:节点ID、集群ID、集群初始化配置、Snapshot文件等),如果未指定,会写在当前目录
ETCD_LISTEN_PEER_URLS 与集群其它成员之间的通信地址
ETCD_LISTEN_CLIENT_URLS 监听本地端口,对外提供服务的地址
ETCD_INITIAL_ADVERTISE_PEER_URLS 通告给集群其它节点,本地的对等URL地址
ETCD_ADVERTISE_CLIENT_URLS 客户端URL,用于通告集群的其余部分信息
ETCD_INITIAL_CLUSTER 集群中的所有信息节点
ETCD_INITIAL_CLUSTER_TOKEN 集群的token,整个集群中保持一致
ETCD_INITIAL_CLUSTER_STATE 初始化集群状态,默认为new

(3)编写启动脚本,由systemd管理etcd

[root@master ~]# 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=/etc/etcd/cfg/etcd.conf
ExecStart=/usr/local/bin/etcd \
--cert-file=/etc/etcd/ssl/server.pem \
--key-file=/etc/etcd/ssl/server-key.pem \
--peer-cert-file=/etc/etcd/ssl/server.pem \
--peer-key-file=/etc/etcd/ssl/server-key.pem \
--trusted-ca-file=/etc/etcd/ssl/ca.pem \
--peer-trusted-ca-file=/etc/etcd/ssl/ca.pem \
--logger=zap
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF

说明一下etcd服务启动几个选项的意义:

配置选项 选项说明
--cert-file 客户端与服务器之间TLS证书文件的路径
--key-file 客户端与服务器之间TLS密钥文件的路径
--peer-cert-file 对等服务器TLS证书文件的路径
--peer-key-file` 对等服务器TLS密钥文件的路径
--trusted-ca-file 签名client证书的CA证书,用于验证client证书
--peer-trusted-ca-file 签名对等服务器证书的CA证书。

(4)分发配置文件和启动脚本

节点1的配置文件和systemd启动脚本都设置好了,所以现在传输一下节点2和节点3的服务配置

#! /bin/bash
for ip in node1 node2
dossh root@$ip "mkdir -pv /etc/etcd/cfg"scp -p /etc/etcd/cfg/etcd.conf root@$ip:/etc/etcd/cfgscp -p /usr/local/bin/{etcd,etcdctl} root@$ip:/usr/local/binscp -p /usr/lib/systemd/system/etcd.service root@$ip:/usr/lib/systemd/system
done

(5)修改其他etcd节点的配置文件

其他另外节点2和节点3分别修改etcd.conf配置文件中的节点名称和当前服务器IP

  • 节点2的etcd配置文件

#[Member]
ETCD_NAME="etcd-02"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.50.131:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.50.131:2379,http://127.0.0.1:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.50.131:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.50.131:2379"
ETCD_INITIAL_CLUSTER="etcd-01=https://192.168.50.128:2380,etcd-02=https://192.168.50.131:2380,etcd-03=https://192.168.50.132:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
  • 节点3的etcd配置文件

#[Member]
ETCD_NAME="etcd-03"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.50.132:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.50.132:2379,http://127.0.0.1:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.50.132:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.50.132:2379"
ETCD_INITIAL_CLUSTER="etcd-01=https://192.168.50.128:2380,etcd-02=https://192.168.50.131:2380,etcd-03=https://192.168.50.132:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"

(6)所有节点启动etcd服务

在master节点执行一个脚本来。

#! /bin/bash
for ip in master node1 node2
dossh root@$ip "systemctl daemon-reload && systemctl enable etcd; systemctl start etcd &"
done

(7)检查etcd集群健康状态

  • 查看集群状态

[root@master ~]# etcdctl --cacert=/etc/etcd/ssl/ca.pem --cert=/etc/etcd/ssl/server.pem --key=/etc/etcd/ssl/server-key.pem --endpoints="https://192.168.50.128:2379,https://192.168.50.131:2379,https://192.168.50.132:2379" endpoint healthhttps://192.168.50.131:2379 is healthy: successfully committed proposal: took = 41.490498ms
https://192.168.50.128:2379 is healthy: successfully committed proposal: took = 46.119028ms
https://192.168.50.132:2379 is healthy: successfully committed proposal: took = 47.186334ms

如果打印的每个etcd节点显示都为healthy,说明集群部署成功。如有问题就查messages日志

  • 查看集群成员

[root@master ~]# etcdctl --cacert=/etc/etcd/ssl/ca.pem --cert=/etc/etcd/ssl/server.pem --key=/etc/etcd/ssl/server-key.pem --endpoints="https://192.168.50.128:2379,https://192.168.50.131:2379,https://192.168.50.132:2379" member list570016793c978bd8, started, etcd-03, https://192.168.50.132:2380, https://192.168.50.132:2379, false
a8ebf47328431d63, started, etcd-02, https://192.168.50.131:2380, https://192.168.50.131:2379, false
b7d726258a4a2d44, started, etcd-01, https://192.168.50.128:2380, https://192.168.50.128:2379, false

5、部署Docker

所有node节点都部署docker服务

(1)添加docker软件yum源

方法:浏览器打开mirrors.aliyun.com网站,找到docker-ce,即可看到镜像仓库yum源

~]# curl -o /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
~]# cat /etc/yum.repos.d/docker-ce.repo
[docker-ce-stable]
name=Docker CE Stable - $basearch
baseurl=https://mirrors.aliyun.com/docker-ce/linux/centos/7/$basearch/stable
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/docker-ce/linux/centos/gpg
...
...

写个脚本执行方便

for i in master node1 node2; do ssh root@$i "curl -o /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo";done

(2)安装docker-ce组件

列出所有可以安装的版本

~]# dnf list docker-ce --showduplicates
docker-ce.x86_64       3:18.09.6-3.el7               docker-ce-stable
docker-ce.x86_64       3:18.09.7-3.el7               docker-ce-stable
docker-ce.x86_64       3:18.09.8-3.el7               docker-ce-stable
docker-ce.x86_64       3:18.09.9-3.el7               docker-ce-stable
docker-ce.x86_64       3:19.03.0-3.el7               docker-ce-stable
docker-ce.x86_64       3:19.03.1-3.el7               docker-ce-stable
docker-ce.x86_64       3:19.03.2-3.el7               docker-ce-stable
docker-ce.x86_64       3:19.03.3-3.el7               docker-ce-stable
docker-ce.x86_64       3:19.03.4-3.el7               docker-ce-stable
docker-ce.x86_64       3:19.03.5-3.el7               docker-ce-stable
.....

这里我们安装18.09版本的docker-ce

~]# dnf install -y  docker-ce-18.09.9 docker-ce-cli-18.09.9

(3)启动docker并设置开机自启动

~]# systemctl enable --now docker

查看版本号,检测docker是否安装成功

~]# docker --version
Docker version 18.09.9, build 039a7df9ba

上面的这种查看docker client的版本的。建议使用下面这种方法查看docker-ce版本号,这种方法把docker的client端和server端的版本号查看的一清二楚。

~]# docker version
Client:Version:           18.09.9API version:       1.39Go version:        go1.11.13Git commit:        039a7df9baBuilt:             Wed Sep  4 16:51:21 2019OS/Arch:           linux/amd64Experimental:      falseServer: Docker Engine - CommunityEngine:Version:          18.09.9API version:      1.39 (minimum version 1.12)Go version:       go1.11.13Git commit:       039a7dfBuilt:            Wed Sep  4 16:22:32 2019OS/Arch:          linux/amd64Experimental:     false

(4)更换docker的镜像仓库地址

默认的镜像仓库地址是docker官方的,国内访问异常缓慢,因此更换为个人阿里云的源。

~]# cat > /etc/docker/daemon.json << EOF
{"registry-mirrors": ["https://f1bhsuge.mirror.aliyuncs.com"]
}
EOF

由于重新加载docker仓库源,所以需要重启docker

~]# systemctl restart docker

6、部署Master Node
我们操作的流程是

  • 制作集群证书

  • 部署kube-apiserver组件

  • 部署kube-controller-manager组件

  • 部署kube-scheduler组件

6.1、创建认证中心(根CA中心)

现在我们创建一套kubernetes集群的根CA证书。用于签发所有的k8s组件。

(1)创建请求证书的json配置文件

[root@master ~]# mkdir ~/TLS/k8s && cd ~/TLS/k8s
[root@master k8s]# cat > ca-config.json << EOF
{"signing": {"default": {"expiry": "87600h"},"profiles": {"kubernetes": {"expiry": "87600h","usages": ["signing","key encipherment","server auth","client auth"]}}}
}
EOF

(2)创建根CA证书签名请求文件

[root@master k8s]# cat > ca-csr.json << EOF
{"CN": "kubernetes","key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "Beijing","ST": "Beijing","O": "k8s","OU": "System"}]
}
EOF

(3)生成证书

[root@master k8s]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
[root@master k8s]# ls *pem
ca-key.pem  ca.pem

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

(1)创建kube-apiserver证书签名请求文件

[root@master k8s]# cat > server-csr.json << EOF
{"CN": "kubernetes","hosts": ["10.0.0.1","127.0.0.1","192.168.50.128","192.168.50.131","192.168.50.132","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

(2)生成证书

[root@master k8s]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server
[root@master k8s]# ls server*pem
server.pem server-key.pem

将上面临时目录生成的证书都复制在kubernetes的证书目录下:

[root@master k8s]# mkdir -pv /etc/kubernetes/ssl
[root@master k8s]# cp -p ./{ca*pem,server*pem} /etc/kubernetes/ssl

6.3、部署kube-apiserver组件

kubernetes现托管在github上面,我们可以看到kubernetes任何版本的更新、下载等信息

点击右侧的Releases按钮,即可看到k8s版本,可以看到目前已经发布了671次版本。

目前最新的文档版本是1.18.5。不过这节课我演示的是1.18.4版本。

只需要下载一个server包就够了,包含了Master和Worker Node二进制文件

详情介绍:https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.18.md

下载链接:https://dl.k8s.io/v1.18.4/kubernetes-server-linux-amd64.tar.gz

  • 国内下载

考虑到科学上网问题,因此给大家介绍一个链接:https://storage.googleapis.com/kubernetes-release/release/v1.18.4/kubernetes-server-linux-amd64.tar.gz

(1)创建目录并解压二进制包

kubernetes证书路径是/etc/kubernetes/ssl

配置文件路径是/etc/kubernetes/cfg

二进制可执行程序包直接放在环境变量/usr/local/bin

日志路径是/var/log/kubernetes

[root@master k8s]# cd && mkdir -pv /etc/kubernetes/cfg /var/log/kubernetes
[root@master ~]# tar xf kubernetes-server-linux-amd64.tar.gz
[root@master ~]# cd kubernetes/server/bin && cp kube-apiserver kube-scheduler kube-controller-manager kubectl /usr/local/bin

(2)部署kube-apiserver

创建kube-apiserver配置文件

[root@master ~]# cat > /etc/kubernetes/cfg/kube-apiserver.conf << EOF
KUBE_APISERVER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/var/log/kubernetes \\
--advertise-address=192.168.50.128 \\
--default-not-ready-toleration-seconds=360 \\
--default-unreachable-toleration-seconds=360 \\
--max-mutating-requests-inflight=2000 \\
--max-requests-inflight=4000 \\
--default-watch-cache-size=200 \\
--delete-collection-workers=2 \\
--bind-address=192.168.50.128 \\
--secure-port=6443 \\
--allow-privileged=true \\
--service-cluster-ip-range=10.0.0.0/24 \\
--service-node-port-range=1024-32767 \\
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \\
--authorization-mode=RBAC,Node \\
--enable-bootstrap-token-auth=true \\
--token-auth-file=/etc/kubernetes/ssl/token.csv \\
--kubelet-client-certificate=/etc/kubernetes/ssl/server.pem \\
--kubelet-client-key=/etc/kubernetes/ssl/server-key.pem \\
--tls-cert-file=/etc/kubernetes/ssl/server.pem  \\
--tls-private-key-file=/etc/kubernetes/ssl/server-key.pem \\
--client-ca-file=/etc/kubernetes/ssl/ca.pem \\
--service-account-key-file=/etc/kubernetes/ssl/ca-key.pem \\
--audit-log-maxage=30 \\
--audit-log-maxbackup=3 \\
--audit-log-maxsize=100 \\
--audit-log-path=/var/log/kubernetes/k8s-audit.log \\
--etcd-servers=https://192.168.50.128:2379,https://192.168.50.131:2379,https://192.168.50.132:2379 \\
--etcd-cafile=/etc/etcd/ssl/ca.pem \\
--etcd-certfile=/etc/etcd/ssl/server.pem \\
--etcd-keyfile=/etc/etcd/ssl/server-key.pem"
EOF
--kubelet-certificate-authority=/etc/kubernetes/ssl/ca.pem \\

为了使用EOF保留换行符,所以要写两个\\

配置文件详细解释如下:

配置选项 选项说明
--logtostderr=false 输出日志到文件中(文件路径由--log-dir指定),不输出到标准错误控制台
--v=2 指定输出日志的级别
--advertise-address 向集群成员通知 apiserver 消息的 IP 地址,这个地址必须能够被集群中其他成员访问,如果 IP 地址为空,将会使用 --bind-address,如果未指定--bind-address,将会使用主机的默认接口地址
--etcd-servers 连接的 etcd 服务器列表 , 形式为(scheme://ip:port),使用逗号分隔
--etcd-cafile 用于etcd 通信的 SSL CA 文件
--etcd-certfile 用于 etcd 通信的的 SSL 证书文件
--etcd-keyfile 用于 etcd 通信的 SSL 密钥文件
--service-cluster-ip-range Service网络地址分配 ,CIDR 表示的 IP 范围,服务的 cluster ip 将从中分配, 一定不要和分配给 nodes 和 pods 的 IP 范围产生重叠
--bind-address 监听 --seure-port 的 IP 地址,被关联的接口必须能够被集群其它节点和 CLI/web 客户端访问,如果为空,则将使用所有接口(0.0.0.0
--secure-port=6443 用于监听具有认证授权功能的 HTTPS 协议的端口,默认值是6443
--allow-privileged 是否启用授权功能
--service-node-port-range Service使用的端口范围
--default-not-ready-toleration-seconds 表示 notReady状态的容忍度秒数
--default-unreachable-toleration-seconds 表示 unreachable状态的容忍度秒数:
--max-mutating-requests-inflight=2000 在给定时间内进行中可变请求的最大数量,当超过该值时,服务将拒绝所有请求,0 值表示没有限制(默认值 200)
--default-watch-cache-size=200 默认监视缓存大小,0 表示对于没有设置默认监视大小的资源,将禁用监视缓存
--delete-collection-workers=2 用于 DeleteCollection 调用的工作者数量,这被用于加速 namespace 的清理( 默认值 1)
--enable-admission-plugins 资源限制的相关配置
--authorization-mode 在安全端口上进行权限验证的插件的顺序列表,以逗号分隔的列表,包括:AlwaysAllow,AlwaysDeny,ABAC,Webhook,RBAC,Node.(默认值 "AlwaysAllow")
--enable-bootstrap-token-auth 启用此选项以允许 'kube-system' 命名空间中的'bootstrap.kubernetes.io/token' 类型密钥可以被用于 TLS 的启动认证
--token-auth-file 声明bootstrap token文件
--kubelet-certificate-authority 证书 authority 的文件路径
--kubelet-client-certificate 用于 TLS 的客户端证书文件路径
--kubelet-client-key 用于 TLS 的客户端证书密钥文件路径
--tls-private-key-file 包含匹配--tls-cert-file的 x509 证书私钥的文件
--service-account-key-file 包含 PEM 加密的 x509 RSA 或 ECDSA 私钥或公钥的文件,用于验证 ServiceAccount 令牌,如果设置该值,--tls-private-key-file 将会被使用,指定的文件可以包含多个密钥,并且这个标志可以和不同的文件一起多次使用
--audit-log-maxage 基于文件名中的时间戳,旧审计日志文件的最长保留天数
--audit-log-maxbackup 旧审计日志文件的最大保留个数
--audit-log-maxsize 审计日志被轮转前的最大兆字节数
--audit-log-path 如果设置,表示所有到apiserver的请求都会记录到这个文件中,‘-’表示写入标准输出

(3)启用TLS Bootstrapping机制

当集群开启了 TLS 认证后,每个节点的 kubelet 组件都要使用由 apiserver 使用的 CA 签发的有效证书才能与 apiserver 通讯;此时如果节点多起来,为每个节点单独签署证书将是一件非常繁琐的事情;

TLS bootstrapping 功能就是让 node节点上的kubelet组件先使用一个预定的低权限用户连接到 apiserver,然后向 apiserver 申请证书,kubelet 的证书由 apiserver 动态签署;

  • 生成token值

[root@localhost ~]# head -c 16 /dev/urandom | od -An -t x | tr -d ' '
14f2afa0b6ccc53350972c4d2942d452
  • 生成token文件:

[root@master ~]# cat > /etc/kubernetes/ssl/token.csv << EOF
14f2afa0b6ccc53350972c4d2942d452,kubelet-bootstrap,10001,"system:node-bootstrapper"
EOF

把上面的token值拿下来,后面的照着写就行。

(4)创建kube-apiserver启动脚本

[root@master ~]# cat > /usr/lib/systemd/system/kube-apiserver.service << EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target[Service]
EnvironmentFile=/etc/kubernetes/cfg/kube-apiserver.conf
ExecStart=/usr/local/bin/kube-apiserver \$KUBE_APISERVER_OPTS
Restart=on-failure
RestartSec=10
Type=notify
LimitNOFILE=65536[Install]
WantedBy=multi-user.target
EOF

上面的变量引用符号$前面加上转义符\,这是在使用EOF写入文件需要注意的地方。

(5)启动并设置开机启动

[root@master ~]# systemctl daemon-reload
[root@master ~]# systemctl start kube-apiserver
[root@master ~]# systemctl enable kube-apiserver

(6)授权kubelet-bootstrap用户允许请求证书

[root@master ~]# kubectl create clusterrolebinding kubelet-bootstrap \
--clusterrole=system:node-bootstrapper \
--user=kubelet-bootstrapclusterrolebinding.rbac.authorization.k8s.io/kubelet-bootstrap created

6.4、部署kube-controller-manager

kube-controller-manager(k8s控制器管理器)是一个守护进程,它通过kube-apiserver监视集群的共享状态(kube-apiserver收集或监视到的一些集群资源状态,供kube-controller-manager或其它客户端watch), 控制器管理器并尝试将当前的状态向所定义的状态迁移(移动、靠近),它本身是有状态的,会修改集群状态信息,如果多个控制器管理器同时生效,则会有一致性问题,所以kube-controller-manager的高可用,只能是主备模式,而kubernetes集群是采用租赁锁实现leader选举,需要在启动参数中加入                                --leader-elect=true

(1)创建controller-manager配置文件

[root@master ~]# cat > /etc/kubernetes/cfg/kube-controller-manager.conf << EOF
KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/var/log/kubernetes \\
--leader-elect=flase \\
--master=127.0.0.1:8080 \\
--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=/etc/kubernetes/ssl/ca.pem \\
--cluster-signing-key-file=/etc/kubernetes/ssl/ca-key.pem  \\
--root-ca-file=/etc/kubernetes/ssl/ca.pem \\
--service-account-private-key-file=/etc/kubernetes/ssl/ca-key.pem \\
--experimental-cluster-signing-duration=87600h0m0s"
EOF

配置文件详细解释如下:

配置选项 选项意义
--leader-elect 高可用时启用选举功能。这里只有一个controller-manager,所以不需要启用选举功能
--master 通过本地非安全本地端口8080连接apiserver
--bind-address 监控地址
--allocate-node-cidrs 是否应在node节点上分配和设置Pod的CIDR
--cluster-cidr Controller Manager在启动时如果设置了--cluster-cidr参数,那么为每个没有设置Spec.PodCIDR的Node节点生成一个CIDR地址,并用该CIDR地址设置节点的Spec.PodCIDR属性,防止不同的节点的CIDR地址发生冲突
--service-cluster-ip-range 集群Services 的CIDR范围
--cluster-signing-cert-file 指定用于集群签发的所有集群范围内证书文件(根证书文件)
--cluster-signing-key-file 指定集群签发证书的key
--root-ca-file 如果设置,该根证书权限将包含service acount的toker secret,这必须是一个有效的PEM编码CA 包
--service-account-private-key-file 包含用于签署service account token的PEM编码RSA或者ECDSA私钥的文件名
--experimental-cluster-signing-duration 证书签发时间

(2)创建controller-manager启动脚本

[root@master ~]# 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]
EnvironmentFile=/etc/kubernetes/cfg/kube-controller-manager.conf
ExecStart=/usr/local/bin/kube-controller-manager \$KUBE_CONTROLLER_MANAGER_OPTS
Restart=on-failure
RestartSec=5[Install]
WantedBy=multi-user.target
EOF

(3)启动并设置开机启动

[root@master ~]# systemctl daemon-reload
[root@master ~]# systemctl start kube-controller-manager
[root@master ~]# systemctl enable kube-controller-manager

6.5、部署kube-scheduler

调度器的职责主要是为新创建的pod在集群中寻找最合适的node,并将pod调度到Node上,Scheduler调度器运行在master节点,它的核心功能是监听apiserver来获取节点上为空的pod,然后为pod创建一个binding指示pod应该调度到哪个节点上,调度结果写入apiserver。

(1)创建scheduler配置文件

[root@master ~]# cat > /etc/kubernetes/cfg/kube-scheduler.conf << EOF
KUBE_SCHEDULER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/var/log/kubernetes \\
--leader-elect=false \\
--master=http://127.0.0.1:8080 \\
--bind-address=127.0.0.1 \\
--address=127.0.0.1"
EOF

(2)创建scheduler服务启动脚本

[root@master ~]# cat > /usr/lib/systemd/system/kube-scheduler.service << EOF
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
After=network.target
[Service]
EnvironmentFile=/etc/kubernetes/cfg/kube-scheduler.conf
ExecStart=/usr/local/bin/kube-scheduler \$KUBE_SCHEDULER_OPTS
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF

(3)启动并设置开机启动

[root@master ~]# systemctl daemon-reload
[root@master ~]# systemctl start kube-scheduler
[root@master ~]# systemctl enable kube-scheduler

6.6、查看集群状态

所有组件都已经启动成功,通过kubectl工具查看当前集群组件状态:

[root@master ~]# kubectl get cs
NAME                 STATUS    MESSAGE             ERROR
scheduler            Healthy   ok
controller-manager   Healthy   ok
etcd-1               Healthy   {"health":"true"}
etcd-2               Healthy   {"health":"true"}
etcd-0               Healthy   {"health":"true"}

看到第二列的状态值都是Healthy,说明Master节点组件运行正常。
7、部署Work Node

对于我们这里的二进制部署的一主多从,在企业中适合测试环境,因此为了更多的复用机器资源,主master节点也应该作为node节点跑pod。

下面依然在master这个节点上操作,让其再成为节点

7.1、拷贝二进制文件至node0节点

  • 复制二进制包

将kubernetes解压的二进制包程序kubelet,kube-proxy复制到本地环境变量路径下。

[root@master ~]# cd kubernetes/server/bin
[root@master bin]# cp kubelet kube-proxy /usr/local/bin
[root@master bin]# cd

7.2、部署kubelet服务

(1)创建kubelet.conf配置文件

[root@master ~]# cat > /etc/kubernetes/cfg/kubelet.conf << EOF
KUBELET_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/var/log/kubernetes \\
--hostname-override=node0 \\
--container-runtime=docker \\
--network-plugin=cni \\
--kubeconfig=/etc/kubernetes/cfg/kubelet.kubeconfig \\
--bootstrap-kubeconfig=/etc/kubernetes/cfg/bootstrap.kubeconfig \\
--config=/etc/kubernetes/cfg/kubelet-config.yml \\
--cert-dir=/etc/kubernetes/ssl \\
--image-pull-progress-deadline=15m \\
--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google_containers/pause-amd64:3.1"
EOF

配置文件解释说明

配置选项 选项意义
--hostname-override 用来配置该节点在集群中显示的主机名,kubelet设置了-–hostname-override参数后,kube-proxy也需要设置,否则会出现找不到Node的情况
--container-runtime 指定容器运行时引擎
--network-plugin 启用CNI网络插件
--kubeconfig kubelet作为客户端使用的kubeconfig认证文件,此文件是由kube-controller-mananger生成的
--bootstrap-kubeconfig 指定令牌认证文件
--config 指定kubelet配置文件
--cert-dir 设置kube-controller-manager生成证书和私钥的目录
--image-pull-progress-deadline 镜像拉取进度最大时间,如果在这段时间拉取镜像没有任何进展,将取消拉取,默认:1m0s
--pod-infra-container-image 每个pod中的network/ipc名称空间容器将使用的镜像

(2)kubelet-config.yml配置参数文件

[root@master ~]# cat > /etc/kubernetes/cfg/kubelet-config.yml << EOF
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: 0.0.0.0
port: 10250
readOnlyPort: 10255
cgroupDriver: cgroupfs
clusterDNS:
- 10.0.0.2
clusterDomain: cluster.local
failSwapOn: false
authentication:anonymous:enabled: falsewebhook:cacheTTL: 2m0senabled: truex509:clientCAFile: /etc/kubernetes/ssl/ca.pem
authorization:mode: Webhookwebhook:cacheAuthorizedTTL: 5m0scacheUnauthorizedTTL: 30s
evictionHard:imagefs.available: 15%memory.available: 100Minodefs.available: 10%nodefs.inodesFree: 5%
maxOpenFiles: 1000000
maxPods: 110
EOF

简单说几个比较重要的选项配置意义

配置选项 选项意义
address kubelet 服务监听的地址
port: 10250 kubelet 服务的端口,默认 10250
readOnlyPort 没有认证/授权的只读 kubelet 服务端口 ,设置为 0 表示禁用,默认 `10255
clusterDNS DNS 服务器的IP地址列表
clusterDomain 集群域名, kubelet 将配置所有容器除了主机搜索域还将搜索当前域

(3)生成bootstrap.kubeconfig文件

生成 kubelet bootstrap kubeconfig 配置文件

[root@master ~]# kubectl config set-cluster kubernetes \--certificate-authority=/etc/kubernetes/ssl/ca.pem \--embed-certs=true \--server=https://192.168.50.128:6443 \--kubeconfig=bootstrap.kubeconfig
[root@master ~]# kubectl config set-credentials "kubelet-bootstrap" \--token=14f2afa0b6ccc53350972c4d2942d452 \--kubeconfig=bootstrap.kubeconfig                          # 与token.csv里保持一致
[root@master ~]# kubectl config set-context default \--cluster=kubernetes \--user="kubelet-bootstrap" \--kubeconfig=bootstrap.kubeconfig
[root@master ~]# kubectl config use-context default --kubeconfig=bootstrap.kubeconfig
[root@master ~]# ls -l *.kubeconfig
-rw------- 1 root root 2168 Jul 14 21:41 bootstrap.kubeconfig

拷贝到配置文件路径/etc/kubernetes/cfg

[root@master ~]# cp -p bootstrap.kubeconfig /etc/kubernetes/cfg

(4)创建kubelet服务启动脚本

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

(5)启动并设置开机启动

[root@master ~]# systemctl daemon-reload
[root@master ~]# systemctl start kubelet
[root@master ~]# systemctl enable kubelet

(6)部署CNI容器网络

CNI,全名叫做:容器网络接口。是CNCF旗下的一个项目,由一组用于配置容器的网络接口的规范和库组成。CNI主要用于解决容器网络互联的配置并支持多种网络模型。

[root@master ~]# cd ~
[root@master ~]#  wget https://github.com/containernetworking/plugins/releases/download/v0.8.6/cni-plugins-linux-amd64-v0.8.6.tgz
[root@master ~]# mkdir -pv /opt/cni/bin
[root@master ~]# tar xf cni-plugins-linux-amd64-v0.8.6.tgz -C /opt/cni/bin
[root@master ~]# ls /opt/cni/bin
bandwidth  bridge  dhcp  firewall  flannel  host-device  host-local  ipvlan  loopback  macvlan  portmap  ptp  sbr  static  tuning  vlan

7.3、批准kubelet证书申请并加入集群

(1)查看kubelet证书请求

[root@master ~]# kubectl get csr
NAME                                                   AGE   SIGNERNAME                                    REQUESTOR           CONDITION
node-csr-N6eV-2UjPO6-dv67Co_lM9BGyF-BQGQ1R_rJz0rGQ3A   22m   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Pending

此命令可以看到所有请求,所有为pending状态,则是需要批准的。

(2)批准申请

把上面的命令的NAME字段的值拿过来。

[root@master ~]# kubectl certificate approve `kubectl get csr | grep "Pending" | awk '{print $1}'`
certificatesigningrequest.certificates.k8s.io/node-csr-N6eV-2UjPO6-dv67Co_lM9BGyF-BQGQ1R_rJz0rGQ3A approved
  • 查看节点

[root@master ~]# kubectl get node
NAME    STATUS     ROLES    AGE   VERSION
node0   NotReady   <none>   3s    v1.18.4

注意:这里的STATUS状态值还是notReady,是因为网络插件还没有部署好。接着往下即可。

7.4、部署kube-proxy服务

kube-proxy是什么,这里就不得不提前说下service,service是一组Pod的抽象集合,它相当于一组Pod的负载均衡器,负责将请求分发到对应的pod,kube-proxy就是负责service的实现的,当请求到达service时,它通过label关联到后端并转发到某个Pod;kube-proxy提供了三种负载均衡模式:用户空间、iptables、ipvs,我们采用的是iptables负载均衡模式。

(1)创建kube-proxy配置文件

[root@master ~]# cat > /etc/kubernetes/cfg/kube-proxy.conf << EOF
KUBE_PROXY_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/var/log/kubernetes \\
--config=/etc/kubernetes/cfg/kube-proxy-config.yml"
EOF

(2)kube-proxy-config.yml配置参数文件

[root@master ~]# cat > /etc/kubernetes/cfg/kube-proxy-config.yml << EOF
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0
healthzBindAddress: 0.0.0.0:10256
metricsBindAddress: 0.0.0.0:10249
clientConnection:burst: 200kubeconfig: /etc/kubernetes/cfg/kube-proxy.kubeconfigqps: 100
hostnameOverride: node0
clusterCIDR: 10.0.0.0/24
EOF

简单说一下上面配置的选项意义

选项配置 选项意义
clientConnection 与kube-apiserver交互时的参数设置
burst: 200 临时允许该事件记录值超过qps设定值
kubeconfig kube-proxy 客户端连接 kube-apiserver 的 kubeconfig 文件路径设置
qps: 100 与kube-apiserver交互时的QPS,默认值5
bindAddress kube-proxy监听地址
healthzBindAddress 用于检查服务的IP地址和端口
metricsBindAddress metrics服务的ip地址和端口。默认:127.0.0.1:10249
clusterCIDR kube-proxy 根据 --cluster-cidr 判断集群内部和外部流量,指定 --cluster-cidr 或 --masquerade-all 选项后 kube-proxy 才会对访问 Service IP 的请求做 SNAT
hostnameOverride 参数值必须与 kubelet 的值一致,否则 kube-proxy 启动后会找不到该 Node,从而不会创建任何 ipvs 规则;

(3)生成kube-proxy.kubeconfig证书

创建证书请求文件

[root@master ~]# cd ~/TLS/k8s
[root@master 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

生成证书

[root@master k8s]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy[root@master k8s]# ls kube-proxy*pem
kube-proxy-key.pem  kube-proxy.pem

(4)生成kubeconfig文件

kube-proxy是作为kube-apiserver的客户端,由于我们启用了TLS,所以需要认证访问,这里我们需要使用到之前生成的证书。

[root@master k8s]# kubectl config set-cluster kubernetes \--certificate-authority=/etc/kubernetes/ssl/ca.pem \--embed-certs=true \--server=https://192.168.50.128:6443 \--kubeconfig=kube-proxy.kubeconfig
[root@master k8s]# kubectl config set-credentials kube-proxy \--client-certificate=./kube-proxy.pem \--client-key=./kube-proxy-key.pem \--embed-certs=true \--kubeconfig=kube-proxy.kubeconfig
[root@master k8s]# kubectl config set-context default \--cluster=kubernetes \--user=kube-proxy \--kubeconfig=kube-proxy.kubeconfig
[root@master k8s]# kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig

拷贝到配置文件指定的路径下:

[root@master k8s]# cp kube-proxy.kubeconfig /etc/kubernetes/cfg/

(5)创建kube-proxy服务启动脚本

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

(6)启动并设置开机启动

[root@master ~]# systemctl daemon-reload
[root@master ~]# systemctl start kube-proxy
[root@master ~]# systemctl enable kube-proxy

7.5、授权apiserver访问kubelet

在执行kubectl exec、run、logs 等命令时,apiserver会转发到kubelet。这里定义 RBAC规则,授权apiserver调用kubelet API"

[root@master ~]# cat > apiserver-to-kubelet-rbac.yaml << EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:annotations:rbac.authorization.kubernetes.io/autoupdate: "true"labels:kubernetes.io/bootstrapping: rbac-defaultsname: system:kube-apiserver-to-kubelet
rules:- apiGroups:- ""resources:- nodes/proxy- nodes/stats- nodes/log- nodes/spec- nodes/metrics- pods/logverbs:- "*"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: system:kube-apiservernamespace: ""
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: system:kube-apiserver-to-kubelet
subjects:- apiGroup: rbac.authorization.k8s.iokind: Username: kubernetes
EOF

(1)访问授权

[root@master ~]# kubectl apply -f apiserver-to-kubelet-rbac.yaml
clusterrole.rbac.authorization.k8s.io/system:kube-apiserver-to-kubelet created
clusterrolebinding.rbac.authorization.k8s.io/system:kube-apiserver created

7.6、部署Flannel网络插件

Flannel是 CoreOS 团队针对 Kubernetes 设计的一个覆盖网络(Overlay Network)工具,其目的在于帮助每一个使用 Kuberentes 的 CoreOS 主机拥有一个完整的子网。Flannel通过给每台宿主机分配一个子网的方式为容器提供虚拟网络,它基于Linux TUN/TAP,使用UDP封装IP包来创建overlay网络,并借助etcd维护网络的分配情况

(1)下载flannel配置文件

[root@master ~]# curl -o kube-flannel.yml  https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

事实上很多用户都不能成功,因为国内网络受限,所以可以这样子来做。修改hosts文件,加上如下解析记录

 199.232.28.133  raw.githubusercontent.com

(2)更换flannel镜像源

编辑镜像源,默认的镜像地址我们修改一下。把yaml文件中所有的quay.io修改为 quay-mirror.qiniu.com

[root@master ~]# sed -i 's/quay.io/quay-mirror.qiniu.com/g' kube-flannel.yml

此时保存保存退出。在master节点执行此命令。

[root@master ~]# kubectl apply -f kube-flannel.yml
podsecuritypolicy.policy/psp.flannel.unprivileged created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds-amd64 created
daemonset.apps/kube-flannel-ds-arm64 created
daemonset.apps/kube-flannel-ds-arm created
daemonset.apps/kube-flannel-ds-ppc64le created
daemonset.apps/kube-flannel-ds-s390x created

这样子就可以成功拉取flannel镜像了。当然你也可以直接使用我提供给大家的kube-flannel.yml文件

  • 查看flannel是否正常

如果你想查看flannel这些pod运行是否正常,使用如下命令:

[root@master ~]# kubectl get pods -n kube-system
NAME                          READY   STATUS    RESTARTS   AGE
kube-flannel-ds-amd64-n5z2w   1/1     Running   0          2m6s

注意:稍等1-3分钟后,如果第三字段STATUS不是处于Running状态的话,并且STATUS字段数值一直在渐渐变大,说明flannel是异常的,需要排查问题所在。

  • 查看节点

[root@master ~]# kubectl get nodes
NAME    STATUS   ROLES    AGE   VERSION
node0   Ready    <none>   10m   v1.18.4

目前节点状态是Ready,表示集群节点现在是可用的

(3)无法拉取镜像解决方法

如果有以下报错:

Normal   BackOff    24m (x6 over 26m)   kubelet, master3   Back-off pulling image "quay-mirror.qiniu.com/coreos/flannel:v0.12.0-amd64"Warning  Failed     11m (x64 over 26m)  kubelet, master3   Error: ImagePullBackOff

或者是

Error response from daemon: Get https://quay.io/v2/: net/http: TLS handshake timeout

上面的这些都表示是网络问题不能拉取镜像,我这里给大家提前准备了flannel的镜像。导入一下就可以了。

[root@master1 ~]# docker load -i flannel.tar

7.7、部署CoreDNS解析插件

CoreDNS用于集群中Pod解析Service的名字,Kubernetes基于CoreDNS用于服务发现功能。

安装CoreDNS1.6.7(目前较新版本)。如果之前修改了PodIP的网段,那么这里需要自行修改此文件的ClusterIP参数。其他可保持不变

spec:selector:k8s-app: kube-dnsclusterIP: 10.0.0.2       #根据自己情况修改此值

(1)构建CoreDNS

[root@master ~]# kubectl apply -f coredns.yaml

查看Pod状态

[root@master ~]# kubectl -n kube-system get pod | grep coredns
coredns-64d575f97f-52kjv      1/1     Running   0          2d5h

(2)解析测试

kubectl run -it --rm busybox-dns --image=busybox:1.28.4 sh
If you don't see a command prompt, try pressing enter./ # nslookup kubernetes
Server:    10.0.0.2
Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.localName:      kubernetes
Address 1: 10.0.0.1 kubernetes.default.svc.cluster.local

只要能出结果,解析就是没有问题的。

8、继续增加Work Node

8.1、部署第二个node节点

(1)拷贝部署好的node相关文件到新节点

在master节点操作,把文件远程复制给node节点

[root@master ~]# scp -p /usr/local/bin/{kubelet,kube-proxy} root@node1:/usr/local/bin
[root@master ~]# scp -pr /etc/kubernetes root@node1:/etc
[root@master ~]# scp -r /usr/lib/systemd/system/{kubelet,kube-proxy}.service root@node1:/usr/lib/systemd/system
[root@master ~]# scp -pr /opt/cni root@node1:/opt

(2)删除kubelet证书和kubeconfig

在node1节点上操作

[root@node1 ~]# rm -rf /etc/kubernetes/cfg/kubelet.kubeconfig
[root@node1 ~]# rm -rf /etc/kubernetes/ssl/kubelet*

(3)修改主机名

[root@node1 ~]# vim /etc/kubernetes/cfg/kubelet.conf

修改为--hostname-override-=node1

[root@node1 ~]# vim /etc/kubernetes/cfg/kube-proxy-config.yml

修改为hostnameOverride: node1

(4)启动并设置开机启动

[root@node1 ~]# systemctl daemon-reload
[root@node1 ~]# systemctl enable --now kubelet kube-proxy

(5)批准node节点申请

下面的是在master节点操作的

[root@master ~]# kubectl get csr
NAME                                                   AGE   SIGNERNAME                                    REQUESTOR           CONDITION
node-csr-N6eV-2UjPO6-dv67Co_lM9BGyF-BQGQ1R_rJz0rGQ3A   41m   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Approved,Issued
node-csr-hJkIg6lFyeDTORq2Y_xNS7qsU0kQCQh_ZqL0Zj_rfrE   98s   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   Pending

上面的CONDITIONPending状态的表示将要被加入集群的节点。所以记录前面的NAME字段

[root@master ~]# kubectl certificate approve `kubectl get csr | grep Pending| awk '{print $1}'`
certificatesigningrequest.certificates.k8s.io/node-csr-hJkIg6lFyeDTORq2Y_xNS7qsU0kQCQh_ZqL0Zj_rfrE approved

(6)查看node状态

稍等两分钟

[root@master ~]# kubectl get nodes
NAME    STATUS   ROLES    AGE   VERSION
node0   Ready    <none>   28m   v1.18.4
node1   Ready    <none>   11m   v1.18.4

8.2、部署第三个node节点

按照上面的前五步继续执行即可。做完之后如下所示:

[root@master ~]# kubectl get nodes
NAME    STATUS   ROLES    AGE   VERSION
node0   Ready    <none>   28m   v1.18.4
node1   Ready    <none>   11m   v1.18.4
node2   Ready    <none>   3m   v1.18.4

至此,二进制单节点集群部署已经完成,接下来我们可以测试一下集群是否可用。

9、测试kubernetes集群

(1)、创建一个nginx的pod

现在我们在kubernetes集群中创建一个nginx的pod,验证是否能正常运行。

在master节点执行一下步骤:

[root@master1 ~]# kubectl create deployment nginx --image=nginx
deployment.apps/nginx created
[root@master1 ~]# kubectl expose deployment nginx --port=80 --type=NodePort
service/nginx exposed

现在我们查看pod和service

[root@master1 ~]# kubectl get pod,svc -o wide

打印的结果中,前半部分是pod相关信息,后半部分是service相关信息。我们看service/nginx这一行可以看出service暴漏给集群的端口是30249。记住这个端口。

然后从pod的详细信息可以看出此时pod在node2节点之上。node2节点的IP地址是192.168.50.132

(2)、访问nginx验证集群

那现在我们访问一下。打开浏览器(建议火狐浏览器),访问地址就是:http://192.168.50.132:30249

10、安装dashboard

10.1、创建dashboard

(1)创建并运行

先把dashboard的配置文件下载下来。由于我们之前已经添加了hosts解析,因此可以下载。

[root@master1 ~]# curl -o recommended.yaml https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta8/aio/deploy/recommended.yaml

默认Dashboard只能集群内部访问,修改Service为NodePort类型,暴露到外部:

大概在此文件的32-44行之间,修改为如下:

kind: Service
apiVersion: v1
metadata:labels:k8s-app: kubernetes-dashboardname: kubernetes-dashboardnamespace: kube-system
spec:type: NodePort       #加上此行ports:- port: 443targetPort: 8443nodePort: 30001     #加上此行,端口30001可以自行定义selector:k8s-app: kubernetes-dashboard
  • 运行此yaml文件

[root@master1 ~]# kubectl apply -f recommended.yaml
namespace/kubernetes-dashboard created
serviceaccount/kubernetes-dashboard created
service/kubernetes-dashboard created
secret/kubernetes-dashboard-certs created
...
service/dashboard-metrics-scraper created
deployment.apps/dashboard-metrics-scraper created

(2)测试是否正常

[root@master1 ~]# kubectl get pods -n kubernetes-dashboard
NAME                                         READY   STATUS    RESTARTS   AGE
dashboard-metrics-scraper-694557449d-mlnl4   1/1     Running   0          2m31s
kubernetes-dashboard-9774cc786-ccvcf         1/1     Running   0          2m31s

主要是看status这一列的值,如果是Running,并且RESTARTS字段的值为0(只要这个值不是一直在渐渐变大),就是正常的,目前来看是没有问题的。我们可以继续下一步。

查看此dashboard的pod运行所在的节点

从上面可以看出,kubernetes-dashboard-9774cc786-ccvcf运行所在的节点是node2上面,并且暴漏出来的端口是30001,所以访问地址是:https://192.168.50.132:30001

(3)浏览器访问URL

用火狐浏览器访问,访问的时候会让输入token,从此处可以查看到token的值。

[root@master1 ~]# kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')

把上面的token值输入进去即可进去dashboard界面。

不过现在我们虽然可以登陆上去,但是我们权限不够还查看不了集群信息,因为我们还没有绑定集群角色,同学们可以先按照上面的尝试一下,再来做下面的步骤

10.2、cluster-admin管理员角色绑定

[root@master1 ~]# kubectl create serviceaccount dashboard-admin -n kube-system
[root@master1 ~]# kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
[root@master1 ~]# kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')

再次使用输出的token登陆dashboard即可。

kubernetes二进制部署单master节点相关推荐

  1. 【重要】kubernetes二进制部署单master节点

    目录 1.安装要求 2.安装规划 3.1.分步骤操作 3.2.一键执行脚本 4.1.安装cfssl证书生成工具 4.2.创建认证中心(根CA中心) 4.3.使用自签CA签发Etcd证书 4.4.部署E ...

  2. 二进制部署 单Master Kubernetes-v1.14.1集群

    一.部署Kubernetes集群 1.1 Kubernetes介绍 Kubernetes(K8S)是Google开源的容器集群管理系统,K8S在Docker容器技术的基础之上,大大地提高了容器化部署应 ...

  3. K8S——单master节点和基于单master节点的双master节点二进制部署(本机实验,防止卡顿,所以多master就不做3台了)

    K8S--单master节点和基于单master节点的双master节点二进制部署 一.准备 二.ETCD集群 1.master节点 2.node节点 三.Flannel网络部署 四.测试容器间互通 ...

  4. 二进制安装多master节点的k8s集群

    二进制安装多master节点的k8s集群 k8s集群角色 IP 主机名 安装的组件 控制节点 192.168.1.180 master1 apiserver,controller-manager,sc ...

  5. Kubernetes二进制部署——Flannel网络

    Kubernetes二进制部署--Flannel网络 一.Flannel简介 二.Flannel原理 三.Flannel的作用 四.Flannel 网络配置 1.node 节点安装 docker 2. ...

  6. Kubernetes二进制部署——证书的制作和ETCD的部署

    Kubernetes二进制部署--证书的制作和ETCD的部署 一.实验环境 自签 SSL 证书 二.ETCD集群部署 1.环境部署 2.master节点 3.node1节点 4.node2节点 5.m ...

  7. 01 kubernetes二进制部署

    kubernetes二进制部署文档-集群部分 文章目录 kubernetes二进制部署文档-集群部分 一.系统规划 1.1 系统组件分布 1.2 部署拓扑 1.3 系统环境 二.初始化系统环境 2.1 ...

  8. K8S二进制部署---单节点master

    目录 一.环境准备 二.部署etcd集群 一.环境准备 先准备3台主机,首先搭建Master单节点集群. 因为 Master 是整个 K8S 集群的大脑,没有 Master 接下来的每一步操作都会变得 ...

  9. Kubernetes 二进制部署 多节点(基于单节点部署,超详细)3

    目录 一.环境准备 二.master02 节点部署 三.负载均衡部署 1.在lb01.lb02节点上操作 2.在 master01 节点上操作 四.部署 Dashboard UI 1.Dashboar ...

最新文章

  1. 用Python解决数据结构与算法问题
  2. python归一化 增大差异_Python逻辑回归模型原理及实际案例应用
  3. centos安装php服务器,在CentOS上安装搭建PHP+Apache+Mysql的服务器环境方法
  4. 分段线性变换与直方图修正
  5. Android RenderScript 关于Compute 的使用
  6. centos 7 单独安装mysql和mysqli和pdo_mysql扩展
  7. java class教程_深入理解Java Class文件格式(七)
  8. iMovie for Mac如何创建分屏效果?
  9. c语言大神,C语言入门大神有话说(一)
  10. python-random模块详解
  11. RGB,ARGB颜色值的表示表示
  12. 解决lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 网络连接不通
  13. 计算器软件测试数据,计算器软件测试报告.pdf
  14. 离散数学课本上的最短路径算法
  15. AI圈就是个马戏团,里面都是一群骗子!AI寒冬论作者再发猛料
  16. 一问三不知之log4j2漏洞简析
  17. UiPath安装教程
  18. MQTT协议(概括与详解)
  19. 世界不曾亏待每个努力的人
  20. 成都奔驰电动折叠后视镜改装电耳 蔚一名车汇

热门文章

  1. 超级计算机是几近制,进制
  2. 2022国赛数学建模思路汇总A题B题C题D题 高教社杯
  3. CSDN 博客,我来了
  4. java优雅关闭io流
  5. 酷鱼G5 plus ITX机箱安装
  6. 中兴B860AV2.1-T(M)-非高安版-当贝纯净桌面线刷固件包
  7. 计算机专业网名英语翻译,英语网名大全带翻译
  8. nc提示java过期_用友U8 软件经常出现“超时已过期”的提示
  9. OC-FUNDATION-NSStringNSMutableStringNSNumberNSValueNSDate
  10. 一些常见的编程语言的选择