Kubernetes二进制安装_初学实践

一. 部署准备

1.1 部署Kubernetes集群的两种方式

目前生产部署Kubernetes集群主要有两种方式:

kubeadm

Kubeadm是一个K8s部署工具,提供kubeadm init和kubeadm join,用于快速部署Kubernetes集群。
Kubeadm官方链接

二进制包

从github下载发行版的二进制包,手动部署每个组件,组成Kubernetes集群。
Kubeadm降低部署门槛,但屏蔽了很多细节,遇到问题很难排查。
如果想更容易可控,推荐使用二进
制包部署Kubernetes集群,虽然手动部署麻烦点,期间可以学习很多工作原理,也利于后期维护。

本文采用二进制包方式来部署Kubernetes1.18集群(单Master)

1.2 安装要求
条件指标
机器要求单节点1,单Master集群3,高可用集群5+
操作系统CentOS7.x-86_x64(其它版本可能与本文档不兼容)
内存(单主机或虚拟机)2GB+
CPU2+
硬盘30G+
swap分区禁止
系统语言英文(使用中文可能会遇到各种莫名其妙的问题)
# 附:查看linux系统内核版本命令
cat /etc/redhat-release # 查看centos系统的版本
uname -a # 查看centos内核版本信息

1.3 集群规划

软件环境:

软件版本
操作系统版本
Docker19-ce
Kubernetes1.18

服务器整体规划:

主机名ip安装组件
m1192.168.118.103kube-apiserver,kube-controller-manager,kube-scheduler,etcd
n1192.168.118.104kubelet,kube-proxy,docker, etcd
1.4 操作系统必要配置初始化
1.4.1 根据规划设置主机名
# 修改/etc/hosts文件(所有主机执行)
vi /etc/hosts
# 添加如下内容
192.168.118.103 m1
192.168.118.104 n1
# 设置主机名(每台主机分别执行)
hostnamectl set-hostname m1 # 主节点执行
hostnamectl set-hostname n1 # node1节点执行

1.4.2 关闭防火墙
# 关闭 firewalld 防火墙(允许 master 和 node 的网络通信)
systemctl stop firewalld
systemctl disable firewalld
systemctl status firewalld
1.4.3 关闭selinux
# 关闭 SElinux 安全模组(让容器可以读取主机的文件系统),所有节点执行

setenforce 0
sed -i.bak`date +%F` 's|SELINUX=.*|SELINUX=disabled|g' /etc/selinux/config

1.4.4 关闭swap

# 关闭 Swap 交换分区(启用了 Swap,则 Qos 策略可能会失效)(所有服务器都执行)

swapoff -a && sed -i.bak "s/\/dev\/mapper\/centos-swap/\#\/dev\/mapper\/centos-swap/g" /etc/fstab

1.4.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  # 生效

1.4.6 时钟同步
# 时间同步(所有节点执行)
yum install ntpdate -y
ntpdate time.windows.com

二、Etcd集群部署

Etcd 是一个分布式键值存储系统,Kubernetes使用Etcd进行数据存储,所以先准备一个Etcd数据库.
为解决Etcd单点故障,应采用集群方式部署,这里使用3台组建集群,可容忍1台机器故障

节点名称IP
m1192.168.118.103
n1192.168.118.104

注:为了节省机器,这里与K8s节点机器复用。也可以独立于k8s集群之外部署,只要apiserver能连接到就行。

2.1 准备cfssl证书生成工具

cfssl是一个开源的证书管理工具,使用json文件生成证书,相比openssl更方便使用。
找任意一台服务器操作,这里用Master节点

wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 --no-check-certificate
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64  --no-check-certificate
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64  --no-check-certificate

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

# 附: wget命令安装方式(所有机器执行)
yum install -y wget

2.2 生成Etcd证书
2.2.1 自签证书颁发机构(CA)
# 创建工作目录
mkdir -p ~/TLS/{etcd,k8s}
cd ~/TLS/etcd

自签CA:

cat > ca-config.json << EOF
{
 "signing": {
  "default": {
   "expiry": "87600h"
 },
  "profiles": {
   "www": {
    "expiry": "87600h",
    "usages": [
      "signing",
      "key encipherment",
      "server auth",
      "client auth"
   ]
  }
 }
}
}
EOF

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

生成证书:

cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
ls *pem
2.2.2 使用自签CA签发Etcd HTTPS证书

创建证书申请文件:

cat > server-csr.json << EOF
{
  "CN": "etcd",
  "hosts": [
  "192.168.118.103",
  "192.168.118.104"
 ],
  "key": {
    "algo": "rsa",
    "size": 2048
 },
  "names": [
   {
      "C": "CN",
      "L": "BeiJing",
      "ST": "BeiJing"
   }
 ]
}
EOF

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

生成证书:

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server
2.3 从Github下载二进制文件

etcd-v3.4.9-linux-amd64.tar.gz文件github下载链接:

2.4 部署Etcd集群

以下在etcd-1(master)上操作,为简化操作,待会将节点1生成的所有文件拷贝到节点2和节点3

2.4.1 创建工作目录并解压二进制包
mkdir /opt/etcd/{bin,cfg,ssl} -p
tar zxvf etcd-v3.4.9-linux-amd64.tar.gz
mv etcd-v3.4.9-linux-amd64/{etcd,etcdctl} /opt/etcd/bin/

2.4.2 创建etcd配置文件
# 注意:这里的主机地址需要根据自己的实际情况进行配置
cat > /opt/etcd/cfg/etcd.conf << EOF
#[Member]
ETCD_NAME="etcd-1"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.118.103:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.118.103:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.118.103:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.118.103:2379"
ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.118.103:2380,etcd-2=https://192.168.118.104: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_PEER_URLS:集群通告地址
ETCD_ADVERTISE_CLIENT_URLS:客户端通告地址
ETCD_INITIAL_CLUSTER:集群节点地址
ETCD_INITIAL_CLUSTER_TOKEN:集群Token
ETCD_INITIAL_CLUSTER_STATE:加入集群的当前状态,new是新集群,existing表示加入已有集
群

2.4.3 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/ca.pem \
--peer-trusted-ca-file=/opt/etcd/ssl/ca.pem \
--logger=zap
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF

2.4.4 拷贝刚才生成的证书
# 把刚才生成的证书拷贝到配置文件中的路径:
cp ~/TLS/etcd/ca*pem ~/TLS/etcd/server*pem /opt/etcd/ssl/

2.4.5 启动并设置开机启动
systemctl daemon-reload
systemctl start etcd #注意: 这里如果单节点首次启动的话,需要等待比较长的时间,最后状态是失败.这是正常情况(可以想象3个节点的Zookeeper集群,如果只有一个节点启动,集群也是不可用的) 
systemctl enable etcd

2.4.6 将上面节点1所有生成的文件拷贝到节点2和节点3
# 拷贝到节点二
scp -r /opt/etcd root@192.168.118.104:/opt/
scp /usr/lib/systemd/system/etcd.service root@192.168.118.104:/usr/lib/systemd/system/


# 附: 如果这里嫌弃scp命令拷贝时需要输入密码麻烦,可配置ssh服务(所有节点执行)
ssh-keygen -t rsa  # 连续按三次回车

ssh-copy-id m1
ssh-copy-id n1

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

vi /opt/etcd/cfg/etcd.conf
# 修改ETCD_NAME以及其它配置项里面涉及到的机器ip

# 节点二配置
#[Member]
ETCD_NAME="etcd-2"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.118.104:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.118.104:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.118.104:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.118.104:2379"
ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.118.103:2380,etcd-2=https://192.168.118.104:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"


# 节点三配置
#[Member]
ETCD_NAME="etcd-3"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.226.146:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.226.146:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.226.146:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.226.146:2379"
ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.226.144:2380,etcd-2=https://192.168.226.145:2380,etcd-3=https://192.168.226.146:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"


配置文件配置完成后,启动etcd并设置开机启动

systemctl daemon-reload
systemctl start etcd 
systemctl enable etcd

2.4.7 查看集群状态
# 查看集群状态
ETCDCTL_API=3  /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem  --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.118.103:2379,\
https://192.168.118.104:2379"  endpoint health

# 查看集群节点列表
ETCDCTL_API=3  /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem  --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.118.103:2379,\
https://192.168.118.104:2379"  member list --write-out=table

如果集群的状态或者节点列表信息异常,请查看日志,可以采用如下命令查看具体报错信息.

systemctl status etcd.service # 查看节点etcd状态
journalctl -u etcd   
journalctl -xe

三、安装Docker

docker-19.03.9.tgz下载链接

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

3.1 解压二进制包
# 以下命令在docker二进制包存放目录下执行
tar zxvf docker-19.03.9.tgz
mv docker/* /usr/bin

3.2 systemd管理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.3 创建配置文件
mkdir /etc/docker
cat > /etc/docker/daemon.json << EOF
{
}
EOF
# 注意开始我在上述文件中配置了:"registry-mirrors":["https://b9pmyelo.mirror.aliyuncs.com"],但是遇到了docker启动失败的情况,所以把上述配置去掉了,只保留一个空的json串
# registry-mirrors 阿里云镜像加速器


3.4 启动并设置开机启动
systemctl daemon-reload
systemctl start docker
systemctl enable docker

启动之后:使用命令查看docker运行状态

systemctl status docker.service

出现如下内容证明安装配置成功

否则,使用journalctl -xe查看具体的报错信息,并根据报错提示解决问题

四、部署Master Node

4.1 生成kube-apiserver证书
4.1.1 自签证书颁发机构(CA)
cd ~/TLS/k8s/
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

生成证书:

cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
ls *pem

注意: 如果执行:

cfssl gencert -initca ca-csr.json | cfssljson -bare ca - #执行命令

#报错如下:
invalid character '?' looking for beginning of object key string
Failed to parse input: unexpected end of JSON input

# 此报错说明json的语法有问题,通常肉眼比较难发现,建议复制粘贴,不要手打

4.1.2 使用自签CA签发kube-apiserver HTTPS证书
cd ~/TLS/k8s/
# 创建证书申请文件
cat > server-csr.json << EOF
{
    "CN": "kubernetes",
    "hosts": [
      "10.0.0.1",
      "127.0.0.1",
      "192.168.118.103",
      "192.168.118.104",
      "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

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

#生成证书
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server

ls server*pem # 列出生成的证书

4.2 从Github下载二进制文件kubernetes-server-linux-amd64.tar

kubernetes-server-linux-amd64.tar下载链接

注:打开链接你会发现里面有很多包,下载一个server包就够了,包含了Master和Worker Node二进制文件

4.3 解压二进制包
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/

4.4 部署kube-apiserver
4.4.1 创建配置文件
vi /opt/kubernetes/cfg/kube-apiserver.conf 

KUBE_APISERVER_OPTS="--logtostderr=false \
--v=2 \
--log-dir=/opt/kubernetes/logs \
--etcd-servers=https://192.168.118.103:2379,https://192.168.118.104:2379 \
--bind-address=192.168.118.103 \
--secure-port=6443 \
--advertise-address=192.168.118.103 \
--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 \
--etcd-cafile=/opt/etcd/ssl/ca.pem \
--etcd-certfile=/opt/etcd/ssl/server.pem \
--etcd-keyfile=/opt/etcd/ssl/server-key.pem \
--audit-log-maxage=30 \
--audit-log-maxbackup=3 \
--audit-log-maxsize=100 \
--audit-log-path=/opt/kubernetes/logs/k8s-audit.log"


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

# 参数说明
--logtostderr:启用日志
---v:日志等级
--log-dir:日志目录
--etcd-servers:etcd集群地址
--bind-address:监听地址
--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证书
--etcd-xxxfile:连接Etcd集群证书
--audit-log-xxx:审计日志

4.4.2 拷贝刚才生成的证书

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

cp ~/TLS/k8s/ca*pem ~/TLS/k8s/server*pem /opt/kubernetes/ssl/
4.4.3 启用 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
 head -c 16 /dev/urandom | od -An -t x | tr -d ' '
79ddd648de9e8c7a54cf63ae579a8262
# 创建上述配置文件中token文件
vim /opt/kubernetes/cfg/token.csv
 79ddd648de9e8c7a54cf63ae579a8262,kubelet-bootstrap,10001,"system:node-bootstrapper"
# 格式:token,用户名,UID,用户组
# 我的token使用的是自己生成的,这部分可自行生成替换

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

4.4.5 启动并设置开机启动
systemctl daemon-reload
systemctl start kube-apiserver
systemctl enable kube-apiserver


注意:这里启动的时候可能会失败! 并且失败了不会给出提示,所以我们要确认kube-apiserver是否启动成功
使用如下命令:

systemctl status kube-apiserver.service

否则:

# 使用如下命令查看启动错误日志,并根据日志提示采取相应解决方案
cat /var/log/messages|grep kube-apiserver|grep -i error

4.4.6 授权kubelet-bootstrap用户允许请求证书
kubectl create clusterrolebinding kubelet-bootstrap \
--clusterrole=system:node-bootstrapper \
--user=kubelet-bootstrap

4.5 部署kube-controller-manager
4.5.1 创建配置文件
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 \\
--master=192.168.118.103: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=/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 \\
--experimental-cluster-signing-duration=87600h0m0s"
EOF

参数说明:

--master:通过本地非安全本地端口8080连接apiserver。
--leader-elect:当该组件启动多个时,自动选举(HA)
--cluster-signing-cert-file/--cluster-signing-key-file:自动为kubelet颁发证书的CA,与apiserver
保持一致

4.5.2 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
4.5.3 启动并设置开机启动
systemctl daemon-reload
systemctl start kube-controller-manager
systemctl enable kube-controller-manager

启动之后.使用如下命令查看状态:

systemctl status kube-controller-manager.service

出现如下内容才说明启动成功!

否则,根据该命令的报错提示去排查解决问题,解决之后重新启动即可

4.6 部署kube-scheduler
4.6.1 创建配置文件
cat > /opt/kubernetes/cfg/kube-scheduler.conf << EOF
KUBE_SCHEDULER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--leader-elect \\
--master=127.0.0.1:8080 \\
--bind-address=127.0.0.1"
EOF

# 配置说明
--master:通过本地非安全本地端口8080连接apiserver。
--leader-elect:当该组件启动多个时,自动选举(HA)

4.6.2 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


4.6.3 启动并设置开机启动
systemctl daemon-reload
systemctl start kube-scheduler
systemctl enable kube-scheduler

# 查看服务运行状态:
systemctl status kube-scheduler.service

如下提示,证明启动成功!

4.6.4 查看集群状态

通过kubectl工具查看当前集群组件状态:

kubectl get cs
NAME                 STATUS      MESSAGE                                                                                     ERROR
controller-manager   Healthy     ok   
scheduler            Healthy     ok                                                                                          
etcd-2               Healthy     {"health":"true"}                                                                           
etcd-1               Healthy     {"health":"true"}                                                                           
etcd-0               Healthy     {"health":"true"}  


五、部署Worker Node

下面的操作如果没有特别强调,还是在Master Node上
即它同时作为Worker Node

5.1 创建工作目录并拷贝二进制文件

在所有worker node创建工作目录:(资源所限,我们将master也视作workernode)

mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs} # master节点已经有这些目录,剩下的节点创建这几个目录

# 以下命令在master节点上执行!!
cd kubernetes/server/bin # 注意,这是一个相对路径,因为每个人配置时所在的路径可能不一样
#这个命令的执行位置和kubernetes-server-linux-amd64.tar.gz文件的上传路径是同一个路径,如果忘记了,可以去4.3部分查看追溯
cp kubelet kube-proxy /opt/kubernetes/bin

拷贝后master节点**/opt/kubernetes/bin/**目录结构如下图:

5.2 部署kubelet
5.2.1 创建配置文件
cat > /opt/kubernetes/cfg/kubelet.conf << EOF
KUBELET_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--hostname-override=192.168.118.104 \\
--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.access.redhat.com/rhel7/pod-infrastructure:latest"
EOF

# 参数说明
--hostname-override:显示名称,集群中唯一
--network-plugin:启用CNI
--kubeconfig:空路径,会自动生成,后面用于连接apiserver
--bootstrap-kubeconfig:首次启动向apiserver申请证书
--config:配置参数文件
--cert-dir:kubelet证书生成目录
--pod-infra-container-image:管理Pod网络容器的镜像

5.2.2 配置参数文件
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: cgroupfs
clusterDNS:
- 10.0.0.2
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


5.2.3 生成bootstrap.kubeconfig文件

KUBE_APISERVER="https://192.168.118.103:6443" # apiserver IP:PORT
#注意这里的TOKEN配置要与: /opt/kubernetes/cfg/token.csv里保持一致
TOKEN="79ddd648de9e8c7a54cf63ae579a8262" 


# 创建上述配置文件中token文件
vim /opt/kubernetes/cfg/token.csv
 79ddd648de9e8c7a54cf63ae579a8262,kubelet-bootstrap,10001,"system:node-bootstrapper"
 
 
 
scp -r kubernetes/  root@192.168.118.104:/opt/
scp -r /usr/bin/kubectl  root@192.168.118.104:/usr/bin/
# 生成 kubelet bootstrap kubeconfig 配置文件
kubectl config set-cluster kubernetes \
  --certificate-authority=/opt/kubernetes/ssl/ca.pem \
  --embed-certs=true \
  --server=${KUBE_APISERVER} \
  --kubeconfig=bootstrap.kubeconfig
  
kubectl config set-credentials "kubelet-bootstrap" \
  --token=${TOKEN} \
  --kubeconfig=bootstrap.kubeconfig
  
kubectl config set-context default \
  --cluster=kubernetes \
  --user="kubelet-bootstrap" \
  --kubeconfig=bootstrap.kubeconfig
  
kubectl config use-context default --kubeconfig=bootstrap.kubeconfig

5.2.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.2.5 启动并设置开机启动
systemctl daemon-reload
systemctl start kubelet
systemctl enable kubelet

# 查看运行状态
systemctl status kubelet.service


出现如下内容证明启动成功!

5.3 批准kubelet证书申请并加入集群
# 查看kubelet证书请求
kubectl get csr
#主节点上执行命令


#批准申请  注意:此命令不要直接复制执行,将后面的node-csr-*  替换为kubectl get csr得到的name值
kubectl certificate approve node-csr-bjm6QMzvUpee4GBFSiQD4rnLJZ8RZorF7VlEVKilKag

# 查看节点
kubectl get node

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

5.4 部署kube-proxy
5.4.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

5.4.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-master
clusterCIDR: 10.0.0.0/24
EOF


5.4.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

# 查看证书
ls kube-proxy*pem

KUBE_APISERVER="https://192.168.118.103:6443"

kubectl config set-cluster kubernetes \
  --certificate-authority=/opt/kubernetes/ssl/ca.pem \
  --embed-certs=true \
  --server=${KUBE_APISERVER} \
  --kubeconfig=kube-proxy.kubeconfig

kubectl config set-credentials kube-proxy \
  --client-certificate=./kube-proxy.pem \
  --client-key=./kube-proxy-key.pem \
  --embed-certs=true \
  --kubeconfig=kube-proxy.kubeconfig


kubectl config set-context default \
  --cluster=kubernetes \
  --user=kube-proxy \
  --kubeconfig=kube-proxy.kubeconfig
  
kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig

# 拷贝配置文件到指定路径:
cp kube-proxy.kubeconfig /opt/kubernetes/cfg/

5.4.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.4.5 启动并设置开机启动
systemctl daemon-reload
systemctl start kube-proxy
systemctl enable kube-proxy

# 查看kube-proxy运行状态
systemctl status kube-proxy

5.5 部署CNI网络

首先下载二进制文件:

[cni-plugins-linux-amd64-v0.8.6.tgz文件下载链接](https://github.com/containernetworking/plugins/releases/download/v0.8.6/cni-plugins-l inux-amd64-v0.8.6.tgz)

解压二进制文件到指定目录

mkdir -p /opt/cni/bin
tar zxvf cni-plugins-linux-amd64-v0.8.6.tgz -C /opt/cni/bin  # 该命令需要在压缩包的同级目录下执行

部署CNI网络:

 wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml --no-check-certificate


# 使用docker下载镜像flannel:v0.12.0-amd64到本地,供后续使用,这里如果遇到的问题,可以参考问题7.8
# 这里我用了一个大佬提供的镜像版本,当然只要镜像合适,可以自己搞或者用其他版本的
docker pull lizhenliang/flannel:v0.12.0-amd64 

# 这个命令的使用就是用我们自己下载的镜像文件替换下载下来的kube-flannel.yml文件里面的
sed -i -r "s#quay.io/coreos/flannel:.*-amd64#lizhenliang/flannel:v0.12.0-amd64#g" kube-flannel.yml # 到这里,可能有的读者会疑问,为什么要使用该命令,具体的解释请参照问题7.7,7.8


默认镜像地址无法访问,修改为docker hub镜像仓库。

kubectl apply -f kube-flannel.yml
kubectl get pods -n kube-system

如下图所示,网络插件配置成功,node准备就绪

5.6 授权apiserver访问kubelet
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-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

5.7 新增加Worker Node
5.7.1 拷贝已部署好的Node相关文件到新节点
# 拷贝到全部的node节点,145,146.   我这里只给出一个节点的命令,master节点执行
scp -r /opt/kubernetes root@192.168.226.145:/opt/
scp -r /usr/lib/systemd/system/{kubelet,kube-proxy}.service root@192.168.226.145:/usr/lib/systemd/system
scp -r /opt/cni/ root@192.168.226.145:/opt/
scp /opt/kubernetes/ssl/ca.pem root@192.168.226.145:/opt/kubernetes/ssl

5.7.2 删除kubelet证书和kubeconfig文件(注意:在普通node上执行,非master)
# 这几个文件是证书申请审批后自动生成的,每个Node不同,必须删除重新生成。
rm /opt/kubernetes/cfg/kubelet.kubeconfig
rm -f /opt/kubernetes/ssl/kubelet*

5.7.3 修改主机名(非master节点执行)
# 这里只给出一台节点的命令
vi /opt/kubernetes/cfg/kubelet.conf
--hostname-override=k8s-node1

vi /opt/kubernetes/cfg/kube-proxy-config.yml
hostnameOverride: k8s-node1

5.7.4 启动并设置开机启动(非master节点执行)
systemctl daemon-reload
systemctl start kubelet
systemctl enable kubelet
systemctl start kube-proxy
systemctl enable kube-proxy

5.7.5 在Master上批准新Node kubelet证书申请(master节点执行)
kubectl get csr
# 注意该命令不要直接复制! 改成自己申请的name!
kubectl certificate approve node-csr-KZGu0Vf0og_7O33qJaokbqlzL2ecYO77eeOShf6ktAU
kubectl certificate approve node-csr-Mf2bxVOO68I4urdHvlEqpFn7FnYyYci3DVb9VWkvwJA

5.7.6 查看Node状态
kubectl get node

如下图,表示OK

注意,执行该命令第一时间节点的状态可能为NotReady,这不一定是有问题,过一段时间刷新即可!

六、部署Dashboard和CoreDNS

6.1 部署Dashboard(master节点执行)
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta8/aio/deploy/recommended.yaml --no-check-certificate

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

vi recommended.yaml

# 找到kind: Servive部分
# 按照下图内容添加: nodePort: 30001
# type: NodePort
# 需要注意添加的位置,以及空格数!

kubectl apply -f recommended.yaml
kubectl get pods,svc -n kubernetes-dashboard

访问地址:

https://ip:30001 #我这里对应的ip为192.168.226.144

# 创建service account并绑定默认cluster-admin管理员集群角色:
kubectl create serviceaccount dashboard-admin -n kube-system
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')


使用输出的token登录Dashboard

初始界面如下图:

6.2 部署CoreDNS

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

# 使用wget命令下载下来的coredns.yaml文件有语法问题,所以我这里提供个没有语法问题的yaml文件

coredns.yaml文件下载链接:

提取码为:pm5t

kubectl apply -f coredns.yaml
kubectl get pods -n kube-system

kubectl run -it --rm dns-test --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.local

Name:      kubernetes
Address 1: 10.0.0.1 kubernetes.default.svc.cluster.local
/ # 


至此,单Master k8s集群部署完成! 撒花

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值