在生产环境中更多是使用二进制方式去安装K8S的各个组件,过程虽然繁琐,但是对于理解K8S是必须的。
一、各节点准备工作部分
# 每个节点关闭防火墙、selinux、swap
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
swapoff -a
# 每个节点配置hostname以及hosts解析
hostnamectl set-hostname k8s-master1
hostnamectl set-hostname k8s-node1
vi /etc/hosts
k8s-master1 192.168.10.101
k8s-master2 192.168.10.102
k8s-node1 192.168.10.103
k8s-node2 192.168.10.104
二、ETCD部分
1、部署一台cfssl节点,用于自建CA颁发自签证书
因为K8S各组件绝大部分是通过HTTPS通信,所以需要先准备好自签证书。这里推荐使用cfssl,比openssl配置简单。然后创建一个根证书,根证书是集群所有节点共享的,后续其它证书都由CA签名。
下载cfssl相关工具到合适的目录
wget http://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget http://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget http://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
#赋予可执行权限并创建证书存放目录
chmod +x cfssl*
mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo
mv cfssljson_linux-amd64 /usr/bin/cfssljson
mv cfssl_linux-amd64 /usr/bin/cfssl
mkdir /data/cfssl
创建CA配置文件,用于配置根证书的使用场景(profile)和有效期等参数。这里配置了20年的有效期,相比kubeadm默认1年的有效期,这个足够长了
cat > /data/cfssl/ca-config.json << EOF
{
"signing": {
"default": {
"expiry": "175200h"
},
"profiles": {
"server": {
"expiry": "175200h",
"usages": [
"signing",
"key encipherment",
"server auth"
]
},
"client": {
"expiry": "175200h",
"usages": [
"signing",
"key encipherment",
"client auth"
]
},
"peer": {
"expiry": "175200h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF
#证书类型
#client certificate:客户端使用,用于服务端认证客户端,例如etcdctl、etcd proxy、fleetctl、docker客户端
#server certificate: 服务端使用,客户端以此验证服务端身份,例如docker服务端、kube-apiserver
#peer certificate: 双向证书,用于etcd集群成员间通信
创建CA证书签名请求文件,有申请过SSL证书的应该知道会向CA机构提交一个CSR文件,这里创建的签名请求文件就是这个CSR文件了
cat > /data/cfssl/ca-csr.json << EOF
{
"CN": "ca",
"hosts": [
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "sichuan",
"L": "chengdu",
"O": "linuxe",
"OU": "ops"
}
],
"ca": {
"expiry": "175200h"
}
}
EOF
#CN: Common Name,浏览器使用该字段验证网站是否合法,一般写的是域名。浏览器使用该字段验证网站是否合法。
#C: Country, 国家
#ST: State,州,省
#L: Locality,地区,城市
#O: Organization Name,组织名称,公司名称
#OU: Organization Unit Name,组织单位名称,公司部门
使用CSR文件生成CA证书和私钥,这步完成后CA自身的证书签发环境就准备好了
cfssl gencert -initca /data/cfssl/ca-csr.json | cfssljson -bare ca - # -bare后面的ca就是指定了证书文件的名字,如ca.pem
ls /data/certs #可以看到生成出来的ca.pem、ca.csr、ca-key.pem(CA私钥需妥善保管)
2、使用CFSSL生成ETCD证书
K8S依赖ETCD服务来存放数据,建议准备三台节点用作ETCD高可用部署,这样即使一个节点挂了也还在正常工作。这里用一台机器作为演示,如果有多台的话也是一样的配置方式
· 为ETCD创建好证书签名请求文件
vi /data/cfssl/etcd-csr.json
{
"CN": "etcd",
"hosts": [
"192.168.0.101",
"192.168.0.102",
"192.168.0.103"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "sichuan",
"L": "chengdu",
"O": "linuxe",
"OU": "ops"
}
]
}
· 使用CSR文件创建peer双向证书
cfssl gencert -ca=/data/cfssl/ca.pem -ca-key=/data/cfssl/ca-key.pem -config=/data/cfssl/ca-config.json -profile=peer /data/cfssl/etcd-csr.json | cfssljson -bare etcd
3、部署ETCD服务(v3.3.18)
· 通过https://github.com/etcd-io/etcd下载ETCD的二进制包并解压到指定目录,然后配置环境变量。本文所用ETCD版本为3.3.18,不同版本配置可能会有不同,请注意
tar zxf etcd-v3.3.18-linux-amd64.tar.gz -C /usr/local/etcd
source /etc/profile
etcd --version
· 为ETCD创建配置文件
mkdir /usr/local/etcd/{conf,data} #注意data目录权限为700
chmod 700 /usr/local/etcd/data
vi /usr/local/etcd/conf/etcd.conf
ETCD_NAME=etcd1 #每个节点的名字
ETCD_DATA_DIR="/usr/local/etcd/data/" #集群数据存放路径
ETCD_LISTEN_PEER_URLS="https://192.168.0.101:2380" #ETCD集群内部通信端口,不对外提供服务,修改为每个节点的IP
ETCD_LISTEN_CLIENT_URLS="https://192.168.0.101:2379,https://127.0.0.1:2379" ##ETCD集群和外部客户端通信端口
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.0.101:2379,https://127.0.0.1:2379" #ETCD向外通告自己监听的端口
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.0.101:2380" #ETCD向外通告自己监听的端口
ETCD_INITIAL_CLUSTER="etcd1=https://192.168.0.101:2380,etcd2=https://192.168.0.102:2380" #所有ETCD节点名称和IP
ETCD_INITIAL_CLUSTER_STATE="new" #是新集群还是需要加入集群
ETCD_INITIAL_CLUSTER_TOKEN="test" #各节点通信时用到的认证token,自定义
#证书相关配置
ETCD_CERT_FILE="/data/cfssl/etcd.pem"
ETCD_KEY_FILE="/data/cfssl/etcd-key.pem"
ETCD_TRUSTED_CA_FILE="/data/cfssl/ca.pem"
ETCD_CLIENT_CERT_AUTH="true"
ETCD_PEER_CERT_FILE="/data/cfssl/etcd.pem"
ETCD_PEER_KEY_FILE="/data/cfssl/etcd-key.pem"
ETCD_PEER_TRUSTED_CA_FILE="/data/cfssl/ca.pem"
ETCD_PEER_CLIENT_CERT_AUTH="true"
· 为ETCD配置启动脚本,然后启动服务
vi /usr/lib/systemd/system/etcd.service
[Unit]
Description=etcd
After=network.target
[Service]
EnvironmentFile=-/usr/local/etcd/conf/etcd.conf
ExecStart=/usr/local/etcd/etcd
[Install]
WantedBy=multi-user.target
· 查看ETCD集群状态,如果发现有节点没有加入的话,看下message日志,通常需要清理data目录然后重启etcd
#http验证方法
etcdctl member list
#https验证方式
/usr/local/etcd/etcdctl --ca-file=/data/cfssl/ca.pem --cert-file=/data/cfssl/etcd.pem --key-file=/data/cfssl/etcd-key.pem --endpoints="https://192.168.0.101:2379" member list
三、K8S Master部署
1、为kube-apiserver创建证书
为K8S部署一个CA,然后颁发证书(这一步尝试使用之前的CA但一直过不去,不知道问题在哪里,新建一个CA就正常了)
cat > /data/cfssl/k8s-ca-config.json << EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF
cat > /data/cfssl/k8s-ca-csr.json << EOF
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "sichuan",
"ST": "chengdu",
"O": "linuxe",
"OU": "ops"
}
]
}
EOF
· 用新建的CA为apiserver创建证书
cat > /data/cfssl/apiserver-csr.json << EOF
{
"CN": "kubernetes",
"hosts": [
"192.168.0.101",
"127.0.0.1",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "sichuan",
"ST": "chengdu",
"O": "linuxe",
"OU": "ops"
}
]
}
EOF
· 用K8S的CA为APISERVER颁发证书
cfssl gencert -initca k8s-ca-csr.json | cfssljson -bare k8s-ca -
cfssl gencert -ca=k8s-ca.pem -ca-key=k8s-ca-key.pem -config=k8s-ca-config.json -profile=kubernetes apiserver-csr.json | cfssljson -bare apiserver
2、部署kube-apiserver(v1.18.6)
· 下载kube-apiserver二进制包,地址如下:https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.18.md#server-binaries(注意下载的是Server binaries)。将下载好的包解压,运行kubectl version查看版本验证
tar zxf kubernetes-server-linux-amd64.tar.gz -C /usr/local/kubernetes
mkdir /usr/local/kubernetes/{conf,bin,logs}
cp /usr/local/kubernetes/server/bin/* /usr/local/kubernetes/bin/
· 创建一个K8S公共参数配置文件,这些公共配置所定义的变量会被其他组件调用
vi /usr/local/kubernetes/conf/kubernetes.conf
KUBE_LOGTOSTDERR="--logtostderr=false" #将日志输出到文件而不是屏幕上
KUBE_LOG_LEVEL="--v=2" #日志级别
KUBE_LOG_DIR="--log-dir=/usr/local/kubernetes/logs/" #日志路径
KUBE_MASTER="--master=127.0.0.1:8080" #API-SERVER的地址
· 创建Kube-apiserver配置文件
vi /usr/local/kubernetes/conf/kube-apiserver.conf
KUBE_API_ADDRESS="--insecure-bind-address=127.0.0.1 --bind-address=0.0.0.0" #apiserver监听地址
KUBE_API_PORT="--insecure-port=8080 --secure-port=6443" #apiserver监听端口
KUBE_ETCD_SERVERS="--etcd-servers=https://192.168.0.101:2379,https://192.168.0.102:2379" #ETCD地址
KUBE_ALLOW_PRIV="--allow-privileged=true" #创建容器的时候是否用管理员权限
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ResourceQuota" #控制器
· 生成token
head -c 16 /dev/urandom | od -An -t x | tr -d ' ' #生成token
cat /data/cfssl/token.csv #将token写入到该文件
ab92cbc669d79d9fb856ba222c376443,kubelet-bootstrap,10001,"system:kubelet-bootstrap"
· 创建Kube-apiserver启动脚本,脚本里用到的变量值就是从配置文件中所读取的
cat > /usr/lib/systemd/system/kube-apiserver.service << EOF
[Unit]
Description=kube-apiserver
After=network.target
[Service]
EnvironmentFile=-/usr/local/kubernetes/conf/kubernetes.conf
EnvironmentFile=-/usr/local/kubernetes/conf/kube-apiserver.conf
ExecStart=/usr/local/kubernetes/bin/kube-apiserver \
$KUBE_API_ADDRESS \
$KUBE_API_PORT \
$KUBE_ETCD_SERVERS \
--etcd-cafile=/data/cfssl/ca.pem --etcd-certfile=/data/cfssl/etcd.pem --etcd-keyfile=/data/cfssl/etcd-key.pem \
$KUBE_LOG_LEVEL \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_DIR \
$KUBE_ALLOW_PRIV \
$KUBE_ADMISSION_CONTROL \
--tls-cert-file=/data/cfssl/apiserver.pem --tls-private-key-file=/data/cfssl/apiserver-key.pem --client-ca-file=/data/cfssl/k8s-ca.pem --service-account-key-file=/data/cfssl/k8s-ca-key.pem --authorization-mode=RBAC,Node --enable-bootstrap-token-auth --token-auth-file=/data/cfssl/token.csv
[Install]
WantedBy=multi-user.target
EOF
#启动服务
systemctl start kube-apiserver
· 验证api-server服务是否正常
kubectl get cs
六、部署调度器kube-scheduler
cat > /usr/lib/systemd/system/kube-scheduler.service << EOF
[Unit]
Description=kube-scheduler
After=network.target
[Service]
EnvironmentFile=-/usr/local/kubernetes/conf/kubernetes.conf
ExecStart=/usr/local/kubernetes/bin/kube-scheduler \
$KUBE_MASTER \
$KUBE_LOG_LEVEL \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_DIR
[Install]
WantedBy=multi-user.target
EOF
#启动服务
systemctl start kube-scheduler
七、部署控制器kube-controller-manager
vi /usr/lib/systemd/system/kube-controller-manager.service
[Unit]
Description=kube-controller-manager
After=network.target
[Service]
EnvironmentFile=-/usr/local/kubernetes/conf/kubernetes.conf
ExecStart=/usr/local/kubernetes/bin/kube-controller-manager \
$KUBE_MASTER \
$KUBE_LOG_LEVEL \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_DIR \
--cluster-name=kubernetes --cluster-signing-cert-file=/data/cfssl/k8s-ca.pem --cluster-signing-key-file=/data/cfssl/k8s-ca-key.pem --root-ca-file=/data/cfssl/ca.pem --service-account-private-key-file=/data/cfssl/k8s-ca-key.pem
[Install]
WantedBy=multi-user.target
#启动服务
systemctl start kube-controller-manager
检查Master各组件情况
/usr/local/kubernetes/bin/kubectl get cs