[容器化技术之十四] K8S集群架构方案及集群搭建之一

一、K8S 集群架构方案

kubernetes 集群架构

Kubernetes 集群组件:

  • etcd 一个高可用的 K/V 键值对存储和服务发现系统
  • flannel 实现夸主机的容器网络的通信
  • kube-apiserver 提供 kubernetes 集群的 API 调用
  • kube-controller-manager 确保集群服务
  • kube-scheduler 调度容器,分配到 Node
  • kubelet 在 Node 节点上按照配置文件中定义的容器规格启动容器
  • kube-proxy 提供网络代理服务


1.1 Kubernetes 集群部署方案

  如下是集群部署策略,1个 master + 2个 node。存储集群 etcd 是单点集群(真实环境为了避免单点故障,一般是多个节点的集群);网络使用的是 flannel 虚拟二次网络。


Kubernetes 具有完备的集群管理能力:

  1. 包括多层次的安全防护和准入机制
  2. 多租户应用支撑能力
  3. 透明的服务注册和服务发现机制
  4. 内建智能负载均衡器
  5. 强大的故障发现和自我修复能力
  6. 服务滚动升级和在线扩容能力
  7. 可扩展的资源自动调度机制
  8. 以及多粒度的资源管理能力

  同时,kubernetes 提供了完善的管理工具,这些工具涵盖了包括开发、部署测试、运维监控在内的各个环节。

  在 kubernetes 中,service(服务)是分布式集群架构的核心,一个 service 对象拥有如下关键特征:

  • 拥有一个唯一指定的名字(比如 mysql-service)。
  • 拥有一个虚拟 IP(Cluster IP、service IP 或 VIP)和端口号。
  • 能够提供某种远程服务能力。
  • 被映射到了提供这种服务能力的一组容器应用上。

  Kubernetes.io 开发了一个交互式教程,通过 WEB 浏览器就能使用预先部署好的一个Kubernetes 集群,快速体验 kubernetes 的功能和应用场景。

  链接https://kubernetes.io/docs/tutorials/kubernetes-basics/
  K8s 官方下载地址https://github.com/kubernetes



1.2 环境准备

  我在我的 PC 上装了三台虚拟机,一台 centos 作为 master,两台 ubuntu 作为 node,信息列表如下:

节点 IP地址 操作系统
master 192.168.27.135 Centos 7.7 - x86_64
node1 192.168.27.133 Ubuntu 16.04 - x86_64
node2 192.168.27.134 Ubuntu 16.04 - x86_64


1.3 集群详情

  • OS:CentOS Linux release 7.7.1908 (Core) 3.10.0-1062.12.1.el7.x86_64
  • Kubernetes: 1.6.0+(最低的版本要求是 1.6)
  • Docker:建议使用 Docker CE
  • Etcd: 3.3.10
  • Flannel: 0.7.1 vxlan 或者 host-gw 网络
  • TLS 认证通信: (所有组件,如 etcd、kubernetes master 和 node)
  • RBAC 授权
  • kubelet TLS BootStrapping
  • kubedns、dashboard、heapster(influxdb、grafana)、EFK(elasticsearch、fluentd、kibana) 集群插件
  • 镜像仓库:私有 docker 镜像仓库 harbor(请自行部署,harbor 提供离线安装包,直接使用 docker-compose 启动即可),不会的请参官文档:
    安装文档:https://github.com/goharbor/harbor/blob/master/docs/installation_guide.md
    配置 https 访问:https://github.com/goharbor/harbor/blob/master/docs/configure_https.md



二、集群环境搭建

  下面的搭建过程使用二进制部署最新的 kubernetes v1.12.3 集群的所有步骤,而不是使用 kubeadm 等自动化方式来部署集群。

  在部署的过程中,将详细列出各组件的启动参数,它们的含义和可能遇到的问题;部署完成后,你将理解系统各组件的交互原理,进而能快速解决实际问题。

提醒

  1. 本文档适用于 CentOS 7.xUbuntu 16.x 及以上版本系统
  2. 由于启用了 TLS 双向认证、RBAC 授权等严格的安全机制,建议从头开始部署,而不要从中间开始,
    否则可能会认证、授权等失败!
  3. 部署过程中需要有很多证书的操作,请从头到尾耐心操作
  4. 该部署操作仅是搭建成了一个可用 kubernetes 集群,而很多地方还需要进行优化,heapster 插件、EFK 插件不一定会用于真实的生产环境中,但是通过部署这些插件,可以让了解到如何部署应用到集群上。


2.1 组件版本和配置策略

2.1.1 组件版本

  • Kubernetes 1.12.3
  • Docker 18.09.0-ce
  • Etcd 3.3.10
  • Flanneld 0.10.0
  • 插件:
     Coredns
     Dashboard
     Heapster (influxdb、grafana)
     Metrics-Server
     EFK (elasticsearch、fluentd、kibana)
  • 镜像仓库:
     docker registry
     harbor


    2.1.2 配置策略

kube-apiserver:

  • 使用节点本地 nginx 4 层透明代理实现高可用;
  • 关闭非安全端口 8080 和匿名访问;
  • 在安全端口 6443 接收 https 请求;
  • 严格的认证和授权策略 (x509、token、RBAC);
  • 开启 bootstrap token 认证,支持 kubelet TLS bootstrapping;
  • 使用 https 访问 kubelet、etcd,加密通信;

kube-controller-manager

  • 3 节点高可用;
  • 关闭非安全端口,在安全端口 10252 接收 https 请求;
  • 使用 kubeconfig 访问 apiserver 的安全端口;
  • 自动 approve kubelet 证书签名请求 (CSR),证书过期后自动轮转;
  • 各 controller 使用自己的 ServiceAccount 访问 apiserver;

kube-scheduler

  • 3 节点高可用;
  • 使用 kubeconfig 访问 apiserver 的安全端口;

kubelet

  • 使用 kubeadm 动态创建 bootstrap token,而不是在 apiserver 中静态配置;
  • 使用 TLS bootstrap 机制自动生成 client 和 server 证书,过期后自动轮转;
  • 在 KubeletConfiguration 类型的 JSON 文件配置主要参数;
  • 关闭只读端口,在安全端口 10250 接收 https 请求,对请求进行认证和授权,拒绝匿名访问和非授权访问;
  • 使用 kubeconfig 访问 apiserver 的安全端口;

kube-proxy

  • 使用 kubeconfig 访问 apiserver 的安全端口;
  • 在 KubeProxyConfiguration 类型的 JSON 文件配置主要参数;
  • 使用 ipvs 代理模式;

集群插件

  • DNS:使用功能、性能更好的 coredns;
  • Dashboard:支持登录认证;
  • Metric:heapster、metrics-server,使用 https 访问 kubelet 安全端口;
  • Log:Elasticsearch、Fluend、Kibana;
  • Registry 镜像库:docker-registry、harbor;

2.2 系统初始化和全局变量

2.2.1 集群机器

  master:192.168.27.135
  node1:192.168.27.133
  node2:192.168.27.134

  我用 VMWare 安装了三台虚拟机,一台使用centos,两台使用ubuntu,下面的 etcd 集群、master 节点、worker 节点均使用这三台机器,但是使用 VMWare 或者 VirtualBox 创建的虚拟机通常 IP 都是动态分配的,我们希望能够固定虚拟机 IP,可以参考 Centos和Ubuntu虚拟机固定IP 进行配置。

注意:

  1. 需要在所有机器上执行下面步骤的初始化命令;
  2. 需要使用具有 root 权限的账号执行这些命令。


    2.2.2 主机名

  设置永久主机名称,然后重新登陆

hostnamectl set-hostname [主机名]      

  设置的主机名保存在 /etc/hostname 文件中,这里我将 135 的 VM 设成 master,133、134 分别设置为 node1node2

  为了让集群中的机器都能解析其他机器的主机名称,需要修改每台机器的 /etc/hosts 文件,添加主机名和 IP 的对应关系:

# 添加完之后应该类似下面的内容
cat /etc/hosts                   
192.168.27.135 master
192.168.27.133 node1
192.168.27.134 node2

  最好再每台机器上 ping 以下每个主机名验证一下。

ping master
ping node1
ping node2



2.2.3 添加 docker 账户

  在每台机器上添加 docker 账户

useradd -m docker



2.2.4 无密码 ssh 登陆其他节点
  如果没有特殊指明,本文档的所有操作均在 master 节点上执行,然后远程分发文件和执行命令,所以需要添加该节点到其它节点的 ssh 信任关系。

  设置 master 可以无密码登录所有节点的 root 账户:

ssh-keygen -t rsa
ssh-copy-id root@master
ssh-copy-id root@node1
ssh-copy-id root@node2

  如果设置完之后使用 ssh node1 测试远程登陆 node1 被拒绝,或者提示没有权限,解决方法参考 SSH远程登陆问题汇总


2.2.5 将可执行文件路径 /opt/k8s/bin 添加到 PATH 变量中

  在每台机器上添加环境变量

echo 'PATH=/opt/k8s/bin:$PATH' >> /root/.bashrc
source /root/.bashrc

  当然,也可以在 /etc/profile 文件中添加环境变量,跟上面相比,区别在于 /etc/profile 属于全局变量,服务器所有的用户都可以使用该变量;/root/.bashrc 属于用户变量,只有 root 用户可以使用。


2.2.6 安装依赖包

Centos:

yum install -y epel-release
yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget
/usr/sbin/modprobe ip_vs



Ubuntu:

apt-get install -y conntrack ipvsadm ntp ipset jq iptables curl sysstat libseccomp
/usr/sbin/modprobe ip_vs

Ubuntu中执行 /usr/sbin/modprobe ip_vs 时报错找不到文件或目录,又用 whereis modprobe 查询了以下,发现可执行文件所在目录为 /sbin/modprobe,所以如果执行报错的话参考将 /usr/sbin/modprobe ip_vs 修改成 /sbin/modprobe ip_vs

  • ipvs 依赖 ipset;
  • ntp 保证各机器系统时间同步;


    2.2.7 关闭防火墙

  由于集群提供服务和通讯时涉及各种端口,为了避免各种报错,在每台机器上都关闭防火墙,清理防火墙规则,设置默认转发策略。

Centos:

systemctl stop firewalld
systemctl disable firewalld
iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat
iptables -P FORWARD ACCEPT



Ubuntu:

sudo ufw disable
iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat
iptables -P FORWARD ACCEPT



2.2.8 关闭 swap 分区

  如果开启了 swap 分区,kubelet 会启动失败(可以通过将参数 --fail-swap-on 设置为 false 来忽略 swap on),故需要在每台机器上关闭 swap 分区。同时注释 /etc/fstab 中相应的条目,防止开机自动挂载 swap 分区:

swapoff -a
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab



2.2.9 关闭 SELinux

  关闭 SELinux,否则后续 K8S 挂载目录可能报错 Permission denied

setenforce 0
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config

  如果执行报错,如下图所示,则是因为机器没装 SELinux的原因,这一步可以跳过




2.2.10 关闭 dnsmasq(可选)

  Linux 系统开启了 dnsmasq 后(如 GUI 环境),将系统 DNS Server 设置为 127.0.0.1,这会导致 docker 容器无法解析域名,需要关闭它:

systemctl stop dnsmasq
systemctl disable dnsmasq

  同样的,如果执行报错找不到服务或目录,证明服务器没有安装 dnsmasq,直接跳过


2.2.11 加载内核模块

modprobe ip_vs_rr
modprobe br_netfilter



2.2.12 优化内核参数

  如果执行中有一些报错不会理会,继续往下执行。

cat > kubernetes.conf <<EOF
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
net.ipv4.tcp_tw_recycle=0
vm.swappiness=0 # 禁止使用 swap 空间,只有当系统 OOM 时才允许使用它
vm.overcommit_memory=1 # 不检查物理内存是否够用
vm.panic_on_oom=0 # 开启 OOM
fs.inotify.max_user_instances=8192
fs.inotify.max_user_watches=1048576
fs.file-max=52706963
fs.nr_open=52706963
net.ipv6.conf.all.disable_ipv6=1
net.netfilter.nf_conntrack_max=2310720
EOF
cp kubernetes.conf /etc/sysctl.d/kubernetes.conf
sysctl -p /etc/sysctl.d/kubernetes.conf
  • 必须关闭 tcp_tw_recycle,否则和 NAT 冲突,会导致服务不通;
  • 关闭 IPV6,防止触发 docker BUG;


    2.2.13 设置系统时区
# 调整系统 TimeZone
timedatectl set-timezone Asia/Shanghai

# 将当前的 UTC 时间写入硬件时钟
timedatectl set-local-rtc 0

# 重启依赖于系统时间的服务
systemctl restart rsyslog
systemctl restart crond



2.2.14 更新系统时间(可选)

ntpdate cn.pool.ntp.org



2.2.15 关闭无关的服务

systemctl stop postfix && systemctl disable postfix



2.2.16 设置 rsyslogd 和 systemd journal

  systemd 的 journald 是 Centos7 缺省的日志记录工具,它记录了所有系统、内核、Service Unit 的日志。

  相比 systemd,journald 记录的日志有如下优势:

  1. 可以记录到内存或文件系统;(默认记录到内存,对应的位置为 /run/log/jounal)
  2. 可以限制占用的磁盘空间、保证磁盘剩余空间;
  3. 可以限制日志文件大小、保存的时间;

  journald 默认将日志转发给 rsyslog,这会导致日志写了多份,/var/log/messages 中包含了太多无关日志,不方便后续查看,同时也影响系统性能。

mkdir /var/log/journal # 持久化保存日志的目录
mkdir /etc/systemd/journald.conf.d
cat > /etc/systemd/journald.conf.d/99-prophet.conf <<EOF
[Journal]
# 持久化保存到磁盘
Storage=persistent
# 压缩历史日志
Compress=yes
SyncIntervalSec=5m
RateLimitInterval=30s
RateLimitBurst=1000
# 最大占用空间 10G
SystemMaxUse=10G
# 单日志文件最大 200M
SystemMaxFileSize=200M
# 日志保存时间 2 周
MaxRetentionSec=2week
# 不将日志转发到 syslog
ForwardToSyslog=no
EOF
systemctl restart systemd-journald



2.2.17 创建相关目录

  创建 k8s 的可执行和工作目录,以及证书目录

mkdir -p /opt/k8s/{bin,work} /etc/{kubernetes,etcd}/cert



2.2.18 如果服务器OS内核较旧,升级内核(可选)

rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
# 安装完成后检查 /boot/grub2/grub.cfg 中对应内核 menuentry 中是否包含 initrd16 配置,如果
没有,再安装一次!
yum --enablerepo=elrepo-kernel install -y kernel-lt
# 设置开机从新内核启动
grub2-set-default 0

  安装内核源文件(可选,在升级完内核并重启机器后执行):

# yum erase kernel-headers
yum --enablerepo=elrepo-kernel install kernel-lt-devel-$(uname -r) kernel-lt-headers-$(uname
-r)



2.2.19 关闭 NUMA(可选)

cp /etc/default/grub{,.bak}
vim /etc/default/grub # 在 GRUB_CMDLINE_LINUX 一行添加 `numa=off` 参数,如下所示:
diff /etc/default/grub.bak /etc/default/grub
6c6
< GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rhgb quiet"
---
> GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rhgb quiet numa=off"

  重新生成 grub2 配置文件

cp /boot/grub2/grub.cfg{,.bak}
grub2-mkconfig -o /boot/grub2/grub.cfg



2.2.20 检查系统内核和模块是否适合运行 docker

curl https://raw.githubusercontent.com/docker/docker/master/contrib/check-config.sh >
check-config.sh
bash ./check-config.sh

  有可能出现下载不到的情况,这是DNS污染的原因,参考修改Hosts临时解决GitHub的raw.githubusercontent.com无法链接的问题即可正常下载。


2.2.21 分发集群环境变量定义脚本(扩容时不需要执行该步骤)

  先来看以下环境变量脚本中定义的环境变量及配置

#!/usr/bin/bash

# 生成 EncryptionConfig 所需的加密 key
export ENCRYPTION_KEY=$(head -c 32 /dev/urandom | base64)

# 集群各机器 IP 数组
export NODE_IPS=(192.168.27.135 192.168.27.133 192.168.27.134)

# 集群各 IP 对应的 主机名数组
export NODE_NAMES=(master node1 node2)

# etcd 集群服务地址列表
export ETCD_ENDPOINTS="https://192.168.27.135:2379,https://192.168.27.133:2379,https://192.168.27.133:2379"

# etcd 集群间通信的 IP 和端口
export ETCD_NODES="master=https://192.168.27.135:2380,node1=https://192.168.27.133:2380,node2=https://192.168.27.134:2380"

# kube-apiserver 的反向代理(kube-nginx)地址端口
# export KUBE_APISERVER="https://127.0.0.1:8443"
export KUBE_APISERVER="https://192.168.27.135:8443"

# 节点间互联网络接口名称
export IFACE="ens33"

# etcd 数据目录
export ETCD_DATA_DIR="/data/k8s/etcd/data"

# etcd WAL 目录,建议是 SSD 磁盘分区,或者和 ETCD_DATA_DIR 不同的磁盘分区
export ETCD_WAL_DIR="/data/k8s/etcd/wal"

# k8s 各组件数据目录
export K8S_DIR="/data/k8s/k8s"

# docker 数据目录
export DOCKER_DIR="/data/k8s/docker"

## 以下参数一般不需要修改

# TLS Bootstrapping 使用的 Token,可以使用命令 head -c 16 /dev/urandom | od -An -t x | tr -d ' ' 生成
BOOTSTRAP_TOKEN="41f7e4ba8b7be874fcff18bf5cf41a7c"

# 最好使用 当前未用的网段 来定义服务网段和 Pod 网段

# 服务网段,部署前路由不可达,部署后集群内路由可达(kube-proxy 保证)
SERVICE_CIDR="10.254.0.0/16"

# Pod 网段,建议 /16 段地址,部署前路由不可达,部署后集群内路由可达(flanneld 保证)
CLUSTER_CIDR="172.30.0.0/16"

# 服务端口范围 (NodePort Range)
export NODE_PORT_RANGE="30000-32767"

# flanneld 网络配置前缀
export FLANNEL_ETCD_PREFIX="/kubernetes/network"

# kubernetes 服务 IP (一般是 SERVICE_CIDR 中第一个IP)
export CLUSTER_KUBERNETES_SVC_IP="10.254.0.1"

# 集群 DNS 服务 IP (从 SERVICE_CIDR 中预分配)
export CLUSTER_DNS_SVC_IP="10.254.0.2"

# 集群 DNS 域名(末尾不带点号)
export CLUSTER_DNS_DOMAIN="cluster.local"

# 将二进制目录 /opt/k8s/bin 加到 PATH 中
export PATH=/opt/k8s/bin:$PATH

  需要根据环境实际情况修改的变量有:


  然后,把全局变量定义脚本拷贝到所有节点的 /opt/k8s/bin 目录,并分发到集群中各个节点

source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    scp /opt/k8s/bin/environment.sh root@${node_ip}:/opt/k8s/bin/
    ssh root@${node_ip} "chmod +x /opt/k8s/bin/*"
  done



2.2.22 参考
  系统内核相关参数参考:https://docs.openshift.com/enterprise/3.2/admin_guide/overcommit.html

2.3 创建 CA 证书和密钥

  为确保安全,kubernetes 系统各组件需要使用 x509 证书对通信进行加密和认证。CA (Certificate Authority) 是自签名的根证书,用来签名后续创建的其它证书。

  这里使用 CloudFlare 的 PKI 工具集 cfssl 创建所有证书。

注意:如果没有特殊指明,本安装步骤的所有操作均在 master 节点上执行,然后远程分发文件和执行命令。


2.3.1 安装 cfssl 工具

sudo mkdir -p /opt/k8s/work/cert && cd /opt/k8s/work
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
mv cfssl_linux-amd64 /opt/k8s/bin/cfssl
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
mv cfssljson_linux-amd64 /opt/k8s/bin/cfssljson
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
mv cfssl-certinfo_linux-amd64 /opt/k8s/bin/cfssl-certinfo
chmod +x /opt/k8s/bin/*
export PATH=/opt/k8s/bin:$PATH

  下载的时候发现下载速度过慢,需要反复下载才能成功,所以这里将环境搭建用到的软件包(cfssl.tar.gz)放在百度云盘上,通过xshell上传到服务器即可,操作参考:如何快捷地将文件通过xshell上传到服务器

链接:https://pan.baidu.com/s/1Zt9SGin72ahERM7ykJ8o7w
提取码:27m2

  将 cfssl.tar.gz 解压并将整个目录下的可执行文件移到 /opt/k8s/bin

  修改可执行文件名字,修改完后如图:




2.3.2 创建根证书 (CA)

  CA 证书是集群所有节点共享的,只需要创建一个 CA 证书,后续创建的所有证书都由它签名。


2.3.3 创建配置文件

  CA 配置文件用于配置根证书的使用场景 (profile) 和具体参数 (usage,过期时间、服务端认证、客户端认证、加密等),后续在签名其它证书时需要指定特定场景。

cd /opt/k8s/work/cert
cat > ca-config.json <<EOF
{
    "signing": {
        "default": {
            "expiry": "87600h"
        },
        "profiles": {
            "kubernetes": {
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth",
                    "client auth"
                ],
                "expiry": "87600h"
            }
        }
    }
}
EOF
  • signing:表示该证书可用于签名其它证书,生成的 ca.pem 证书中 CA=TRUE;
  • server auth:表示 client 可以用该该证书对 server 提供的证书进行验证;
  • client auth:表示 server 可以用该该证书对 client 提供的证书进行验证;


    2.3.4 创建证书签名请求文件
cd /opt/k8s/work/cert
cat > ca-csr.json <<EOF
{
    "CN": "kubernetes",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "BeiJing",
            "L": "BeiJing",
            "O": "k8s",
            "OU": "study163"
        }
    ]
}
EOF
  • CN:Common Name,kube-apiserver 从证书中提取该字段作为请求的用户名 (User Name),浏览器使用该字段验证网站是否合法;
  • O:Organization,kube-apiserver 从证书中提取该字段作为请求用户所属的组 (Group);
  • kube-apiserver 将提取的 User、Group 作为 RBAC 授权的用户标识;


    2.3.5 生成 CA 证书和私钥
cd /opt/k8s/work/cert
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
ls ca*




2.3.6 分发 CA 证书和私钥
  将生成的 CA 证书、秘钥文件、配置文件拷贝到所有节点的 /etc/kubernetes/cert 目录下:

cd /opt/k8s/work/cert
source /opt/k8s/bin/environment.sh # 导入 NODE_IPS 环境变量
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "mkdir -p /etc/kubernetes/cert"
scp ca*.pem ca-config.json root@${node_ip}:/etc/kubernetes/cert
done




2.3.7 CA 资料参考
各种 CA 证书类型:
https://github.com/kubernetes-incubator/apiserver-builder/blob/master/docs/concepts/auth.md

2.4 部署 kubectl 命令行工具

  kubectl 是 kubernetes 集群的命令行管理工具,这了介绍安装和配置的步骤。

  kubectl 默认从 ~/.kube/config 文件读取 kube-apiserver 地址、证书、用户名等信息,如果没有配置,执行 kubectl 命令时可能会出错:

kubectl get pods

注意:

  1. 如果没有特殊指明,本文档的所有操作均在 master 节点上执行,然后远程分发文件和执行命令。
  2. 本文档只需要部署一次,生成的 kubeconfig 文件是通用的,可以拷贝到需要执行 kubeclt 命令的机器上。

2.4.1 下载和分发 kubectl 命令行工具

  下载和解压:

cd /opt/k8s/work
wget https://dl.k8s.io/v1.12.3/kubernetes-client-linux-amd64.tar.gz
tar -xzvf kubernetes-client-linux-amd64.tar.gz

  分发到所有使用 kubectl 的节点:

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
scp kubernetes/client/bin/kubectl root@${node_ip}:/opt/k8s/bin/
ssh root@${node_ip} "chmod +x /opt/k8s/bin/*"
done




2.4.2 创建 admin 证书和私钥

  kubectl 与 apiserver https 安全端口通信,apiserver 对提供的证书进行认证和授权。

  kubectl 作为集群的管理工具,需要被授予最高权限。这里创建具有最高权限的 admin 证书。
创建证书签名请求:

cd /opt/k8s/work/cert
cat > admin-csr.json <<EOF
{
  "CN": "admin",
  "hosts": [],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "system:masters",
      "OU": "study163"
    }
  ]
}
EOF
  • 为 system:masters,kube-apiserver 收到该证书后将请求的 Group 设置为 system:masters;

  • 预定义的 ClusterRoleBinding cluster-admin 将 Group system:masters 与 Role cluster-admin 绑定,该Role 授予所有 API的权限;

  • 该证书只会被 kubectl 当做 client 证书使用,所以 hosts 字段为空;



      生成证书和私钥

cd /opt/k8s/work/cert
cfssl gencert -ca=/opt/k8s/work/cert/ca.pem \
  -ca-key=/opt/k8s/work/cert/ca-key.pem \
  -config=/opt/k8s/work/cert/ca-config.json \
  -profile=kubernetes admin-csr.json | cfssljson -bare admin
ls admin*




2.4.3 创建 kubeconfig 文件

  kubeconfig 为 kubectl 的配置文件,包含访问 apiserver 的所有信息,如 apiserver 地址、CA 证书和自身使用的证书;

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh

# 设置集群参数
kubectl config set-cluster kubernetes \
  --certificate-authority=/opt/k8s/work/cert/ca.pem \
  --embed-certs=true \
  --server=${KUBE_APISERVER} \
  --kubeconfig=kubectl.kubeconfig

# 设置客户端认证参数
kubectl config set-credentials admin \
  --client-certificate=/opt/k8s/work/cert/admin.pem \
  --client-key=/opt/k8s/work/cert/admin-key.pem \
  --embed-certs=true \
  --kubeconfig=kubectl.kubeconfig

# 设置上下文参数
kubectl config set-context kubernetes \
  --cluster=kubernetes \
  --user=admin \
  --kubeconfig=kubectl.kubeconfig
  
# 设置默认上下文
kubectl config use-context kubernetes --kubeconfig=kubectl.kubeconfig
  • --certificate-authority:验证 kube-apiserver 证书的根证书;

  • --client-certificate、--client-key:刚生成的 admin 证书和私钥,连接 kube-apiserver 时使用;

  • --embed-certs=true:将 ca.pem 和 admin.pem 证书内容嵌入到生成的 kubectl.kubeconfig 文件中(不加时,写入的是证书文件路径);


      生成 kubectl.kubeconfig 文件



    2.4.4 分发 kubeconfig 文件

  分发到所有使用 kubectl 命令的节点,在所有节点的 root 用户目录下创建一个 .kube 的目录,并将分发的文件重命名为 config 放置其中。

cd /opt/k8s/work
source /opt/k8s/bin/environment.sh
for node_ip in ${NODE_IPS[@]}
  do
    echo ">>> ${node_ip}"
    ssh root@${node_ip} "mkdir -p ~/.kube"
    scp kubectl.kubeconfig root@${node_ip}:~/.kube/config
  done


  查询每个节点的 /root/.kube/config 配置文件

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容