K8s简介
Kubernetes(简称k8s)是Google在2014年6月开源的一个容器集群管理系统,使用Go语言开发,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效,Kubernetes提供了资源调度、部署管理、服务发现、扩容缩容、监控,维护等一整套功能。,努力成为跨主机集群的自动部署、扩展以及运行应用程序容器的平台。 它支持一系列容器工具, 包括Docker等。
# kubernetes
注意 本文所有操作均在所有节点执行 本文环境
名称
配置
Kubernetes版本
v1.17.3
Cluster Pod CIDR
10.244.0.0/16
Cluster Service CIDR
10.250.0.0/24
kubernetes service
10.250.0.1
dns service
10.250.0.10
本文档主要介绍在裸机环境下以二进制的方式安装部署kubernetes
本次文档主要是对于kubernetes 1.17.3版本
内容主要有环境准备安装配置docker 升级内核 调整系统参数
环境准备
主机名
IP
组件
配置
k8s-master1
192.168.220.101
apiserver、controller-manager、schedule、docker-ce
2核 4G
k8s-master2
192.168.220.102
apiserver、controller-manager、schedule、docker-ce
2核 4G
k8s-node1
192.168.220.103
kube-proxy、kubelet、docker-ce,etcd
2核 4G
k8s-node1
192.168.220.104
kube-proxy、kubelet、docker-ce,etcd
2核 4G
k8s-node1
192.168.220.105
kube-proxy、kubelet、docker-ce,etcd
2核 4G
以下操作除非具体说明的步骤 其他的均在所有节点执行
环境变量 此环境变量为主节点(控制节点)的主机名和IP地址
1 2 3 4 5 6 7 8 9 10 11 export VIP=192.168.220.100export MASTER1_HOSTNAME=k8s-master1export MASTER1_IP=192.168.220.101export MASTER2_HOSTNAME=k8s-master2export MASTER2_IP=192.168.220.102export NODE1_HOSTNAME=k8s-node1export NODE1_IP=192.168.220.103export NODE1_HOSTNAME=k8s-node2export NODE1_IP=192.168.220.104export NODE1_HOSTNAME=k8s-node3export NODE1_IP=192.168.220.105
SSH免密/时间同步/主机名修改 · SSH免密
· NTP时间同步
· 主机名修改
· 环境变量生成
· Host 解析
这里需要说一下,所有的密钥分发以及后期拷贝等都在master1上操作,因为master1做免密了
k8s集群所有的机器都需要进行host解析
1 2 3 4 5 6 7 cat >> /etc/hosts << EOF 192.168.220.101 k8s-master1192.168.220.102 k8s-master2192.168.220.103 k8s-node1192.168.220.104 k8s-node2192.168.220.105 k8s-node3EOF
批量免密
# 做免密前请修改好主机名对应的host
1 2 3 4 5 6 7 8 9 10 11 yum - y install expect ssh- keygen - t rsa - P "" - f / root/ .ssh/ id_rsa for i in 192.168 .220.101 192.168 .220.102 192.168 .220.103 192.168 .220.104 192.168 .220.105 ;do expect - c " spawn ssh-copy-id -i /root/.ssh/id_rsa.pub root@$i expect { \" *yes/no*\" {send \" yes\r \" ; exp_continue} \" *password*\" {send \" quhuixx\r \" ; exp_continue} \" *Password*\" {send \" quhuixx\r \" ;} } " done
切记所有机器需要自行设定ntp,否则不只HA下apiserver通信有问题,各种千奇百怪的问题。
1 2 3 4 5 6 yum -y install ntp systemctl enable ntpd systemctl start ntpd ntpdate -u time1 .aliyun .com hwclock --systohc timedatectl set-timezone Asia /Shanghai
测试通信
1 for i in k8s-master1 k8s-master2 k8s-node1 k8s-node2 k8s-node3; do ssh root@$i "hostname" ;done
升级内核 安装内核语言编译器(内核是用perl语言编写的)
下载密钥和yum源
导入密钥
安装7版本的yum源文件
1 yum -y install https://www.elrepo.org/elrepo-release-7 .0 -4 .el7.elrepo.noarch.rpm
安装 ml版本 5版本的内核名字叫ml
1 yum --enablerepo= "elrepo-kernel" -y install kernel-ml.x86_64
附:4.4版本内核安装方法
1 yum --enablerepo= "elrepo-kernel" -y install kernel-lt.x86_64
然后配置从新的内核启动
然后重新生成grub2.cfg 使虚拟机使用新内核启动
1 grub2-mkconfig -o /boot/g rub2/grub.cfg
调整系统内核参数 1 2 3 4 5 6 7 8 9 10 11 12 cat >> /etc/sysctl.conf <<EOF net.ipv4.ip_forward=1 vm.swappiness=0 vm.overcommit_memory=1 vm.panic_on_oom=0 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
然后执行sysctl -p 使配置的内核响应参数生效
关闭防火墙、selinux、swap、NetworkManager 1 2 3 4 5 6 7 8 9 systemctl stop firewalld systemctl disable firewalld iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat iptables -P FORWARD ACCEPT sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab setenforce 0 sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config systemctl stop NetworkManager systemctl disable NetworkManager
修改资源限制 1 2 3 4 5 6 echo "* soft nofile 65536" >> /etc/security/limits.conf echo "* hard nofile 65536" >> /etc/security/limits.conf echo "* soft nproc 65536" >> /etc/security/limits.conf echo "* hard nproc 65536" >> /etc/security/limits.conf echo "* soft memlock unlimited" >> /etc/security/limits.conf echo "* hard memlock unlimited" >> /etc/security/limits.conf
常用软件安装 1 yum -y install bridge-utils chrony ipvsadm ipset sysstat conntrack libseccomp wget tcpdump screen vim nfs-utils bind-utils wget socat telnet sshpass net-tools sysstat lrzsz yum-utils device-mapper-persistent-data lvm2 tree nc lsof strace nmon iptraf iftop rpcbind mlocate ipvsadm
加载内核ipvs模块 1 2 3 4 5 6 7 8 9 10 11 12 13 cat > /etc/sysconfig/modules/ipvs.modules <<EOF # !/bin/bash modprobe -- ip_vs modprobe -- ip_vs_rr modprobe -- ip_vs_wrr modprobe -- ip_vs_sh modprobe -- nf_conntrack_ipv4 EOF chmod 755 /etc/sysconfig/modules/ipvs.modules bash /etc/sysconfig/modules/ipvs.modules lsmod | grep -e ip_vs -e nf_conntrack_ipv4
安装docker-ce: 添加yun源
1 2 3 4 5 6 7 8 tee /etc/yum .repos.d/docker-ce.repo <<-'EOF' [aliyun-docker-ce] name=aliyun-docker-ce baseurl=https://mi rrors.aliyun.com/docker-ce/ linux/centos/ 7 /x86_64/ stable/ enable=1 gpgcheck=1 gpgkey=https://mi rrors.aliyun.com/docker-ce/ linux/centos/g pg EOF
安装docker-ce
1 yum -y install docker-ce
重启docker并设置为开机自启
1 2 3 system ctl daemon-reloadsystem ctl restart dockersystem ctl enable docker
然后重启系统 验证内核是否升级成功 下载命令 下载cfssl以及cfssljson命令 此举目的是下载创建证书以及配置文件需要的命令
PKI基础概念
什么是PKI?
公开密钥基础建设(英语:Public Key Infrastructure,缩写:PKI),又称公开密钥基础架构、公钥基础建设、公钥基础设施、公开密码匙基础建设或公钥基础架构,是一组由硬件、软件、参与者、管理政策与流程组成的基础架构,其目的在于创造、管理、分配、使用、存储以及撤销数字证书。(节选维基百科)
PKI是借助CA(权威数字证书颁发/认证机构)将用户的个人身份跟公开密钥链接在一起,它能够确保每个用户身份的唯一性,这种链接关系是通过注册和发布过程实现,并且根据担保级别,链接关系可能由CA和各种软件或在人为监督下完成。PKI用来确定链接关系的这一角色称为RA(Registration Authority, 注册管理中心),RA能够确保公开密钥和个人身份链接,可以防抵赖,防篡改。在微软的公钥基础建设下,RA又被称为CA,目前大多数称为CA。
PKI组成要素
从上面可以得知PKI的几个主要组成要素,用户(使用PKI的人或机构),认证机构(CA,颁发证书的人或机构),仓库(保存证书的数据库)等。
非对称加密
本文提到的密钥均为非对称加密,有公钥和私钥之分,并且他们总是成对出现,它们的特点就是其中一个加密的数据,只能使用另一个解密,即使它本身也无法解密,也就是说公钥加密的,私钥可以解密,私钥加密的,公钥可以解密。
证书签名请求CSR
它是向CA机构申请数字证书时使用的请求文件,这里的CSR不是证书,而向权威证书颁发机构获得签名证书的申请,当CA机构颁发的证书过期时,你可以使用相同的CSR来申请新的证书,此时key不变。
数字签名
数字签名就是“非对称加密+摘要算法”,其目的不是为了加密,而是为了防抵赖或者他们篡改数据。其核心思想是:比如A要给B发送数据,A先用摘要算法得到数据的指纹,然后用A的私钥加密指纹,加密后的指纹就是A的签名,B收到数据和A的签名后,也用同样的摘要算法计算指纹,然后用A公开的公钥解密签名,比较两个指纹,如果相同,说明数据没有被篡改,确实是A发过来的数据。假设C想改A发给B的数据来欺骗B,因为篡改数据后指纹会变,要想跟A的签名里面的指纹一致,就得改签名,但由于没有A的私钥,所以改不了,如果C用自己的私钥生成一个新的签名,B收到数据后用A的公钥根本就解不开。(来源于网络)
数字证书格式
数字证书格式有很多,比如.pem,.cer或者.crt等。
PKI工作流程
下图来源于网络,上半部分最右边就是CA机构,可以颁发证书。证书订阅人,首先去申请一个证书,为了申请这个证书,需要去登记,告诉它,我是谁,我属于哪个组织,到了登记机构,再通过CSR,发送给CA中心,CA中心通过验证通过之后 ,会颁发一对公钥和私钥,并且公钥会在CA中心存一份;证书订阅人拿到证书以后,部署在服务器;
当用户访问我们的web服务器时,它会请求我们的证书,服务器会把公钥发送给我们的客户端,客户端会去验证我们证书的合法性,客户端是如何验证证书是否有效呢?CA中心会把过期证书放在CRL服务器上面 ,这个CRL服务会把所有过期的证书形成一条链条,所以他的性能非常的差,所以又推出了OCSP程序,OCSP可以就一个证书进行查询,它是否过期,浏览器可以直接去查询OCSP响应程序,但OCSP响应程序效率还不是很高,最终往往我们会把web服务器如nginx有一个ocsp开关,当我们打开这个开关以后,会有nginx服务器主动的去ocsp服务器去查询,这样大量的客户端直接从web服务器就可以直接获取到证书是否有效。
CFSSL介绍
CFSSL是什么?
cfssl是使用go编写,由CloudFlare开源的一款PKI/TLS工具。主要程序有cfssl,是CFSSL的命令行工具,cfssljson用来从cfssl程序获取JSON输出,并将证书,密钥,CSR和bundle写入文件中。
安装CFSSL 可能下载时间较长
1 2 3 4 5 6 7 8 wget https:// pkg.cfssl.org/R1.2/ cfssl_linux-amd64 wget https:// pkg.cfssl.org/R1.2/ cfssljson_linux-amd64 wget https:// pkg.cfssl.org/R1.2/ cfssl-certinfo_linux-amd64 chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64 mv cfssl_linux-amd64 /usr/ local/bin/ cfssl mv cfssljson_linux-amd64 /usr/ local/bin/ cfssljson mv cfssl-certinfo_linux-amd64 /usr/ bin/cfssl-certinfo cfssl version
版本应该是1.2.0及以上版本
显示信息
1 2 3 Version : 1 .2 .0 Revision : devRuntime : go1.6
生成证书 注意 本文所有操作均在master1节点执行 主要内容为生成kubernetes集群所需要的各种证书
主要有两个部分 生成etcd的证书 和生成kubernetes组件的证书
生成etcd证书 1 创建生成证书和临时存放证书的目录
1 mkdir /root/ ssl/{etcd,kubernetes} -p
进入etcd目录
2 创建用来生成CA文件的JSON配置文件
此CA文件只用与etcd的证书
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 cat << EOF | tee ca-config .json{ "signing" : { "default" : { "expiry" : "876000h" }, "profiles" : { "etcd" : { "expiry" : "876000h" , "usages" : [ "signing" , "key encipherment" , "server auth" , "client auth" ] } } } } EOF
server auth 表示client可以对使用该ca对server提供的证书进行验证
client auth 表示server可以使用该ca对client提供的证书进行验证
3 创建用来生成CA证书签名请求(CSR)的JSON配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 cat << EOF | tee ca-csr .json{ "CN" : "etcd CA" , "key" : { "algo" : "rsa" , "size" : 2048 }, "names" : [ { "C" : "CN" , "L" : "Beijing" , "ST" : "Beijing" } ] } EOF
4 生成CA证书和私钥
1 cfssl gencert -initca ca -csr.json | cfssljson -bare ca
输出内容
1 2 3 4 5 6 2019 /10/ 12 19 :35 :14 [INFO] generating a new CA key and certificate from CSR2019 /10/ 12 19 :35 :14 [INFO] generate received request2019 /10/ 12 19 :35 :14 [INFO] received CSR2019 /10/ 12 19 :35 :14 [INFO] generating key: rsa-2048 2019 /10/ 12 19 :35 :14 [INFO] encoded CSR2019 /10/ 12 19 :35 :14 [INFO] signed certificate with serial number 76399392328271693420688681207409409662642174207
查看生成的CA证书和私钥
输出内容
5 创建etcd证书请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 cat << EOF | tee etcd-csr .json{ "CN" : "etcd" , "hosts" : [ "200.200.100.71" , "200.200.100.72" , "200.200.100.73" ], "key" : { "algo" : "rsa" , "size" : 2048 }, "names" : [ { "C" : "CN" , "L" : "Beijing" , "ST" : "Beijing" } ] } EOF
6 生成etcd证书和私钥
1 2 3 4 5 cfssl gencert \ -ca =ca.pem \ -ca-key =ca-key.pem \ -config =ca-config.json \ -profile =etcd etcd-csr.json | cfssljson -bare etcd
输出内容
1 2 3 4 5 6 7 8 9 2019 /10 /12 19 :39 :16 [INFO ] generate received request2019 /10 /12 19 :39 :16 [INFO ] received CSR2019 /10 /12 19 :39 :16 [INFO ] generating key: rsa-2048 2019 /10 /12 19 :39 :17 [INFO ] encoded CSR2019 /10 /12 19 :39 :17 [INFO ] signed certificate with serial number 276878925110307603699002043209122885766807800060 2019 /10 /12 19 :39 :17 [WARNING ] This certificate lacks a "hosts" field. This makes it unsuitable for websites. For more information see the Baseline Requirements for the Issuance and Management of Publicly-Trusted Certificates, v.1 .1 .6 , from the CA/Browser Forum (https://cabforum.org);specifically, section 10.2 .3 ("Information Requirements").
7 查看生成的所有etcd证书
输出的4个文件
1 2 3 4 ca-key.pem ca.pem etcd-key.pem etcd.pem
生成kubernetes组件证书 切换到kubernetes组件证书申请和存放目录
1 cd /root/ ssl/kubernetes/
新建CA配置文件 用于kubernetes集群的组件和admin角色
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 cat > ca-config .json <<EOF { "signing" : { "default" : { "expiry" : "8760h" }, "profiles" : { "kubernetes" : { "expiry" : "8760h" , "usages" : [ "signing" , "key encipherment" , "server auth" , "client auth" ] } } } } EOF
新建CA凭证签发请求文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 cat > ca-csr.json <<EOF { "CN" : "Kubernetes" , "hosts" : [ "127.0.0.1" , "200.200.100.71" , "200.200.100.72" , "200.200.100.73" , "200.200.100.70" ], "key" : { "algo" : "rsa" , "size" : 2048 }, "names" : [ { "C" : "China" , "L" : "Beijing" , "O" : "Kubernetes" , "OU" : "Beijing" , "ST" : "Beijing" } ] } EOF
生成CA凭证和私钥
1 cfssl gencert -initca ca -csr.json | cfssljson -bare ca
输出信息
1 2 3 4 5 6 2019 /10/ 12 19 :56 :26 [INFO] generating a new CA key and certificate from CSR2019 /10/ 12 19 :56 :26 [INFO] generate received request2019 /10/ 12 19 :56 :26 [INFO] received CSR2019 /10/ 12 19 :56 :26 [INFO] generating key: rsa-2048 2019 /10/ 12 19 :56 :26 [INFO] encoded CSR2019 /10/ 12 19 :56 :26 [INFO] signed certificate with serial number 679742542757179200541008226092035525850208663173
查看创建的证书和私钥
输出文件
client与server凭证 创建admin client 凭证签发请求文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 cat > admin -csr.json <<EOF { "CN": "admin", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "China", "L": "Beijing", "O": "system:masters", "OU": "Kubernetes", "ST": "Beijing" } ] } EOF
创建admin client 凭证和私钥
1 2 3 4 5 6 cfssl gencert \ -ca =ca.pem \ -ca-key =ca-key.pem \ -config =ca-config.json \ -profile =kubernetes \ admin-csr.json | cfssljson -bare admin
输出信息
1 2 3 4 5 6 7 8 9 2019 /10 /12 19 :59 :38 [INFO ] generate received request2019 /10 /12 19 :59 :38 [INFO ] received CSR2019 /10 /12 19 :59 :38 [INFO ] generating key: rsa-2048 2019 /10 /12 19 :59 :38 [INFO ] encoded CSR2019 /10 /12 19 :59 :38 [INFO ] signed certificate with serial number 514625224786356937263551808946632861542829130401 2019 /10 /12 19 :59 :38 [WARNING ] This certificate lacks a "hosts" field. This makes it unsuitable for websites. For more information see the Baseline Requirements for the Issuance and Management of Publicly-Trusted Certificates, v.1 .1 .6 , from the CA/Browser Forum (https://cabforum.org);specifically, section 10.2 .3 ("Information Requirements").
查看生成的文件
1 2 ls admin *.pem admin -key.pem admin .pem
生成kubelet客户端凭证 kubernetes使用special-purpose authorization mode(被称作 Node Authorizer) 授权来自kubelet的API请求
为了通过Node Authorizer的授权,kubelet 必须使用一个署名为system:node:的凭证来证明它属于system:nodes用户组。
本节将会给每台节点(包括master节点)创建凭证和私钥
创建master1节点的凭证签发请求文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 cat << EOF | tee k8s-master1-csr .json { "CN" : "system:node:$ {MASTER1_HOSTNAME}" , "key" : { "algo" : "rsa" , "size" : 2048 }, "names" : [ { "C" : "China" , "L" : "Beijing" , "O" : "system:nodes" , "OU" : "Kubernetes" , "ST" : "Beijing" } ] } EOF
生成master节点的证书和私钥
1 2 3 4 5 6 7 cfssl gencert \ -ca =ca.pem \ -ca-key =ca-key.pem \ -config =ca-config.json \ -hostname =${MASTER1_HOSTNAME} ,${MASTER1_IP} \ -profile =kubernetes \ k8s-master1-csr.json | cfssljson -bare k8s-master1
输出信息
1 2 3 4 5 6 2019 /10/ 12 20 :08 :33 [INFO] generate received request2019 /10/ 12 20 :08 :33 [INFO] received CSR2019 /10/ 12 20 :08 :33 [INFO] generating key: rsa-2048 2019 /10/ 12 20 :08 :33 [INFO] encoded CSR2019 /10/ 12 20 :08 :33 [INFO] signed certificate with serial number 340503546795644080420594727795505971193705840974
输出的文件
1 2 ls k8s-master*.pem k8s-master1-key.pem k8s-master1.pem
创建master2节点的凭证签发请求文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 cat << EOF | tee k8s-master2-csr .json{ "CN" : "system:node:$ {MASTER2_HOSTNAME}" , "key" : { "algo" : "rsa" , "size" : 2048 }, "names" : [ { "C" : "China" , "L" : "Beijing" , "O" : "system:nodes" , "OU" : "Kubernetes" , "ST" : "Beijing" } ] } EOF
生成master2节点的证书和私钥
1 2 3 4 5 6 7 cfssl gencert \ -ca =ca.pem \ -ca-key =ca-key.pem \ -config =ca-config.json \ -hostname =${MASTER2_HOSTNAME} ,${MASTER2_IP} \ -profile =kubernetes \ k8s-master2-csr.json | cfssljson -bare k8s-master2
输出信息
1 2 3 4 5 6 2019 /10/ 12 20 :08 :33 [INFO] generate received request2019 /10/ 12 20 :08 :33 [INFO] received CSR2019 /10/ 12 20 :08 :33 [INFO] generating key: rsa-2048 2019 /10/ 12 20 :08 :33 [INFO] encoded CSR2019 /10/ 12 20 :08 :33 [INFO] signed certificate with serial number 340503546795644080420594727795505971193705840974
输出的文件
1 2 ls k8s-master*.pem k8s-master1-key.pem k8s-master1.pem k8s-master2-key.pem k8s-master2.pem
创建master3节点的凭证签发请求文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 cat << EOF | tee k8s-master3-csr .json{ "CN" : "system:node:$ {MASTER3_HOSTNAME}" , "key" : { "algo" : "rsa" , "size" : 2048 }, "names" : [ { "C" : "China" , "L" : "Beijing" , "O" : "system:nodes" , "OU" : "Kubernetes" , "ST" : "Beijing" } ] } EOF
生成k8s-node节点的证书和私钥
1 2 3 4 5 6 7 cfssl gencert \ -ca =ca.pem \ -ca-key =ca-key.pem \ -config =ca-config.json \ -hostname =${MASTER3_HOSTNAME} ,${MASTER3_IP} \ -profile =kubernetes \ k8s-master3-csr.json | cfssljson -bare k8s-master3
输出信息
1 2 3 4 5 2019 /10/ 12 20 :11 :22 [INFO] generate received request2019 /10/ 12 20 :11 :22 [INFO] received CSR2019 /10/ 12 20 :11 :22 [INFO] generating key: rsa-2048 2019 /10/ 12 20 :11 :22 [INFO] encoded CSR2019 /10/ 12 20 :11 :22 [INFO] signed certificate with serial number 329201759031912279536498320815194792351902510021
输出的文件
1 2 ls k8s-master3*.pem k8s-master3-key.pem k8s-master3.pem
创建k8s-node1节点的凭证签发请求文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 cat << EOF | tee k8s-node1-csr .json{ "CN" : "system:node:$ {NODE1_HOSTNAME}" , "key" : { "algo" : "rsa" , "size" : 2048 }, "names" : [ { "C" : "China" , "L" : "Beijing" , "O" : "system:nodes" , "OU" : "Kubernetes" , "ST" : "Beijing" } ] } EOF
生成k8s-node1节点的证书和私钥
1 2 3 4 5 6 7 cfssl gencert \ -ca =ca.pem \ -ca-key =ca-key.pem \ -config =ca-config.json \ -hostname =${NODE1_HOSTNAME} ,${NODE1_IP} \ -profile =kubernetes \ k8s-node1-csr.json | cfssljson -bare k8s-node1
输出信息
1 2 3 4 5 2019 /10/ 12 20 :16 :27 [INFO] generate received request2019 /10/ 12 20 :16 :27 [INFO] received CSR2019 /10/ 12 20 :16 :27 [INFO] generating key: rsa-2048 2019 /10/ 12 20 :16 :27 [INFO] encoded CSR2019 /10/ 12 20 :16 :27 [INFO] signed certificate with serial number 11529605845303364851563251013549393798169113866
输出文件
1 2 ls k8 s-node1 *.pem k8 s-node1 -key.pem k8 s-node1 .pem
8 创建master组件需要的证书
创建kube-controller-manager客户端凭证 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 cat > kube-controller-manager-csr.json <<EOF{ "CN" : "system:kube-controller-manager" , "key" : { "algo" : "rsa" , "size" : 2048 }, "names" : [ { "C" : "China" , "L" : "Beijing" , "O" : "system:kube-controller-manager" , "OU" : "Kubernetes" , "ST" : "Beijing" } ] } EOF
生成证书和私钥
1 2 3 4 5 6 cfssl gencert \ -ca =ca.pem \ -ca-key =ca-key.pem \ -config =ca-config.json \ -profile =kubernetes \ kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager
输出信息
1 2 3 4 5 6 7 8 9 2019 /10 /12 20 :29 :06 [INFO ] generate received request2019 /10 /12 20 :29 :06 [INFO ] received CSR2019 /10 /12 20 :29 :06 [INFO ] generating key: rsa-2048 2019 /10 /12 20 :29 :06 [INFO ] encoded CSR2019 /10 /12 20 :29 :06 [INFO ] signed certificate with serial number 173346030426505912970345315612511532042452194730 2019 /10 /12 20 :29 :06 [WARNING ] This certificate lacks a "hosts" field. This makes it unsuitable for websites. For more information see the Baseline Requirements for the Issuance and Management of Publicly-Trusted Certificates, v.1 .1 .6 , from the CA/Browser Forum (https://cabforum.org);specifically, section 10.2 .3 ("Information Requirements").
输出文件
1 2 ls kube-con*.pem kube-controller-manager-key.pem kube-controller-manager.pem
创建kube-proxy客户端凭证 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 cat <<EOF |tee kube-proxy-csr .json { "CN" : "system:kube-proxy" , "hosts" : [], "key" : { "algo" : "rsa" , "size" : 2048 }, "names" : [ { "C" : "China" , "L" : "Beijing" , "O" : "system:node-proxier" , "OU" : "Kubernetes" , "ST" : "Beijing" } ] } EOF
生成证书和私钥
1 2 3 4 5 6 cfssl gencert \ -ca =ca.pem \ -ca-key =ca-key.pem \ -config =ca-config.json \ -profile =kubernetes \ kube-proxy-csr.json | cfssljson -bare kube-proxy
输出信息
1 2 3 4 5 6 7 8 9 2019 /10 /12 20 :31 :11 [INFO ] generate received request2019 /10 /12 20 :31 :11 [INFO ] received CSR2019 /10 /12 20 :31 :11 [INFO ] generating key: rsa-2048 2019 /10 /12 20 :31 :11 [INFO ] encoded CSR2019 /10 /12 20 :31 :11 [INFO ] signed certificate with serial number 3973180903081703880688638425637585151040946194 2019 /10 /12 20 :31 :11 [WARNING ] This certificate lacks a "hosts" field. This makes it unsuitable for websites. For more information see the Baseline Requirements for the Issuance and Management of Publicly-Trusted Certificates, v.1 .1 .6 , from the CA/Browser Forum (https://cabforum.org);specifically, section 10.2 .3 ("Information Requirements").
输出文件
1 2 ls kube-proxy*.pem kube-proxy-key.pem kube-proxy.pem
创建kube-scheduler凭证签发 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 cat <<EOF | tee kube-scheduler-csr .json { "CN" : "system:kube-scheduler" , "key" : { "algo" : "rsa" , "size" : 2048 }, "names" : [ { "C" : "China" , "L" : "Beijing" , "O" : "system:kube-scheduler" , "OU" : "Kubernetes" , "ST" : "Beijing" } ] } EOF
生成证书
1 2 3 4 5 6 cfssl gencert \ -ca =ca.pem \ -ca-key =ca-key.pem \ -config =ca-config.json \ -profile =kubernetes \ kube-scheduler-csr.json | cfssljson -bare kube-scheduler
输出信息
1 2 3 4 5 6 7 8 9 2019 /10 /12 20 :18 :57 [INFO ] generate received request2019 /10 /12 20 :18 :57 [INFO ] received CSR2019 /10 /12 20 :18 :57 [INFO ] generating key: rsa-2048 2019 /10 /12 20 :18 :57 [INFO ] encoded CSR2019 /10 /12 20 :18 :57 [INFO ] signed certificate with serial number 56094122509645103760584094055826646549201635795 2019 /10 /12 20 :18 :57 [WARNING ] This certificate lacks a "hosts" field. This makes it unsuitable for websites. For more information see the Baseline Requirements for the Issuance and Management of Publicly-Trusted Certificates, v.1 .1 .6 , from the CA/Browser Forum (https://cabforum.org);specifically, section 10.2 .3 ("Information Requirements").
输出文件
1 2 ls kube-sch*.pem kube-scheduler-key.pem kube-scheduler.pem
创建kubernetes 证书 为了保证客户端与kubernetes API的认证,kubernetes API Server 凭证中必须包含master的静态IP地址
此IP地址使用上面配置的环境变量
创建kubernetes API Server 凭证签发请求文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 cat <<EOF | tee kubernetes-csr .json { "CN" : "kubernetes" , "hosts" : [ "127.0.0.1" , "200.200.100.71" , "200.200.100.72" , "200.200.100.73" , "200.200.100.70" , "10.250.0.1" , "kubernetes" , "kubernetes.default" , "kubernetes.default.svc" , "kubernetes.default.svc.cluster" , "kubernetes.default.svc.cluster.local" ], "key" : { "algo" : "rsa" , "size" : 2048 }, "names" : [ { "C" : "China" , "L" : "Beijing" , "O" : "Kubernetes" , "OU" : "Kubernetes" , "ST" : "Beijing" } ] } EOF
生成kubernetes API Server 凭证与私钥
1 2 3 4 5 6 cfssl gencert \ -ca =ca.pem \ -ca-key =ca-key.pem \ -config =ca-config.json \ -profile =kubernetes \ kubernetes-csr.json | cfssljson -bare kubernetes
输出信息
1 2 3 4 5 2019 /10/ 12 20 :23 :03 [INFO] generate received request2019 /10/ 12 20 :23 :03 [INFO] received CSR2019 /10/ 12 20 :23 :03 [INFO] generating key: rsa-2048 2019 /10/ 12 20 :23 :03 [INFO] encoded CSR2019 /10/ 12 20 :23 :03 [INFO] signed certificate with serial number 319608271292119912072742471756939391576493389087
输出文件
1 2 ls kubernetes*.pem kubernetes-key.pem kubernetes.pem
Service Account 证书
创建凭证签发问
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 cat > service -account -csr.json <<EOF { "CN" : "service-accounts" , "key" : { "algo" : "rsa" , "size" : 2048 }, "names" : [ { "C" : "China" , "L" : "Beijing" , "O" : "Kubernetes" , "OU" : "Kubernetes" , "ST" : "Beijing" } ] } EOF
生成证书和私钥
1 2 3 4 5 6 cfssl gencert \ -ca =ca.pem \ -ca-key =ca-key.pem \ -config =ca-config.json \ -profile =kubernetes \ service-account-csr.json | cfssljson -bare service-account
输出信息
1 2 3 4 5 6 7 8 9 2019 /10 /12 20 :25 :31 [INFO ] generate received request2019 /10 /12 20 :25 :31 [INFO ] received CSR2019 /10 /12 20 :25 :31 [INFO ] generating key: rsa-2048 2019 /10 /12 20 :25 :31 [INFO ] encoded CSR2019 /10 /12 20 :25 :31 [INFO ] signed certificate with serial number 538955391110960009078645942634491132767864895292 2019 /10 /12 20 :25 :31 [WARNING ] This certificate lacks a "hosts" field. This makes it unsuitable for websites. For more information see the Baseline Requirements for the Issuance and Management of Publicly-Trusted Certificates, v.1 .1 .6 , from the CA/Browser Forum (https://cabforum.org);specifically, section 10.2 .3 ("Information Requirements").
输出文件
1 2 ls service*.pem service-account-key.pem service-account.pem
9 拷贝etcd证书到相应节点的相应目录
创建etcd目录
1 2 3 4 for host in k8s-master1 k8s-master2 k8s-master3;do echo "---$host ---" ssh root@$host "mkdir /usr/local/etcd/{bin,ssl,data,json,src} -p" ; done
拷贝etcd证书
1 2 3 4 5 6 7 8 9 10 11 12 13 cd ../etcd/ 拷贝方法一; scp etcd-key.pem etcd.pem ca.pem ca-key.pem k8s-master1:/usr/ local/etcd/ ssl/ scp etcd-key.pem etcd.pem ca.pem ca-key.pem k8s-master2:/usr/ local/etcd/ ssl/ scp etcd-key.pem etcd.pem ca.pem ca-key.pem k8s-master3:/usr/ local/etcd/ ssl/ 拷贝方法二; for host in k8s-master1 k8s-master2 k8s-master3; \ do echo "--- $host---" scp -r *.pem $host :/usr/ local/etcd/ ssl/ done
配置和生成kubernetes配置文件 本文档是kubernetes1.17.3二进制安装的第四篇
注意 本文所有操作均在master节点执行 本文将主要介绍创建kubeconfig配置文件 她们是kubernetes客户端与API Server 认证与鉴权的保证
kubectl是kubernetes命令行客户端,一般情况集群都开启了TLS认证,kubectl或其它客户端每次与集群kube-apiserver交互都少不了身份验证,目前有两种常用认证方式,使用证书和token,这两种方式也是最通用的方式,本节简单说下kubectl客户端如何使用证书的认证方式访问集群。
使用证书的方式,一般情况下我们需要创建一个kubeconfig配置文件,这个文件用来组织有关集群、用户、命名空间和身份认证机制的信息。kubectl使用kubeconfig配置文件来查找选择集群所需信息,并且集群kube-apiserver进行通信,kubectl默认查到${HOME}/.kube目录下面的config文件,当然也可以通过设置KUBECONFIG环境变量或者在命令行使用–kubeconfig参数指定kubeconfig配置文件。
配置详情
步骤
配置选项
选项说明
1. 设置集群信息
set-cluster
kubectl config 设置集群信息时使用
–certificate-authority
设置集群的根证书路径
–embed-certs
将–certificate-authority根证书写入到kubeconfig中
–server
指定访问集群的socket
–kubeconfig
kubeconfig配置文件路径
2. 设置客户端参数
set-credentials
kubectl config 设置客户端认证信息
–client-certificate
指定kubectl使用的证书路径
–client-key
指定kubectl使用的私钥路径
–embed-certs
将kubectl使用的证书和私钥写入到kubeconfig中
–kubeconfig
kubeconfig配置文件路径
3. 设置上下文信息
set-context
kubectl config 设置上下文参数
–cluster
配置使用哪个集群信息,set-cluster中设置的
–user
配置使用哪个客户端,set-credentials中设置的
–kubeconfig
kubeconfig配置文件路径
4. kubeconfig中使用哪个上下文
use-context
kubectl config 设置使用哪个上下文信息
客户端认证配置
本节将会创建用于 kube-proxy kube-controll-manager kube-scheduler 和kubelet 的kubeconfig文件
kubelet配置文件 为了确保Node Authorizer授权 kubelet配置文件中的客户端证书必须匹配Node名字
Node名字还使用生成证书那一节配置的环境变量
为所有节点创建kubeconfig配置(都在master节点操作)
生成配置文件所在的目录就在上一节生成kubernetes组件所在的目录
首先安装kubectl
这里一次性将所有需要的软件都安装上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 wget --timestamping \ "https://storage.googleapis.com/kubernetes-release/release/v1.17.3/bin/linux/amd64/kube-apiserver" \ "https://storage.googleapis.com/kubernetes-release/release/v1.17.3/bin/linux/amd64/kube-controller-manager" \ "https://storage.googleapis.com/kubernetes-release/release/v1.17.3/bin/linux/amd64/kube-scheduler" \ "https://storage.googleapis.com/kubernetes-release/release/v1.17.3/bin/linux/amd64/kubectl" chmod +x kube-apiserver kube-controller-manager kube-scheduler kubectl https:// dl.k8s.io/v1.17.3/ kubernetes-server-linux-amd64.tar.gz tar -zxvf /root/ kubernetes-server-1.17 .3 -linux-amd64.tar.gz --strip-components=3 -C /usr/ local/bin kubernetes/ server/bin/ kube{let,ctl,-apiserver,-controller-manager,-scheduler,-proxy} for host in k8s-master2 k8s-master3; do echo "---$host---" scp /usr/ local/bin/ kube{let,ctl,-apiserver,-controller-manager,-scheduler,-proxy} $host :/usr/ local/bin/ done scp /usr/ local/bin/ kube{let,-proxy} k8s-node1:/usr/ local/bin/ cd /root/ ssl/kubernetes/
不用环境变量的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 kubectl config set-cluster kubernetes-training \ --certificate-authority=ca.pem \ --embed-certs=true \ --server=https://${VIP}:8443 \ --kubeconfig=k8s-master1.kubeconfig kubectl config set-credentials system:node: k8s-master1 \ --client-certificate=k8s-master1.pem \ --client-key=k8s-master1-key.pem \ --embed-certs=true \ --kubeconfig=k8s-master1.kubeconfig kubectl config set-context default \ --cluster=kubernetes-training \ --user=system:node:k8s-master1 \ --kubeconfig=k8s-master1.kubeconfig kubectl config use-context default --kubeconfig=k8s-master1.kubeconfig
使用环境变量的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 kubectl config set-cluster kubernetes-training \ --certificate-authority=ca.pem \ --embed-certs=true \ --server=https://${VIP}:8443 \ --kubeconfig=${MASTER1_HOSTNAME}.kubeconfig kubectl config set-credentials system:node: ${MASTER1_HOSTNAME } \ --client-certificate=${MASTER1_HOSTNAME}.pem \ --client-key=${MASTER1_HOSTNAME}-key.pem \ --embed-certs=true \ --kubeconfig=${MASTER1_HOSTNAME}.kubeconfig kubectl config set-context default \ --cluster=kubernetes-training \ --user=system:node:${MASTER1_HOSTNAME} \ --kubeconfig=${MASTER1_HOSTNAME}.kubeconfig kubectl config use-context default --kubeconfig=${MASTER1_HOSTNAME}.kubeconfig
输出文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ls k8s-master *config k8s-master1 .kubeconfig kubectl config set-cluster kubernetes-training \ --certificate-authority=ca.pem \ --embed-certs=true \ --server=https://${VIP}:8443 \ --kubeconfig=k8s-master2.kubeconfig kubectl config set-credentials system:node: k8s-master2 \ --client-certificate=k8s-master2.pem \ --client-key=k8s-master2-key.pem \ --embed-certs=true \ --kubeconfig=k8s-master2.kubeconfig kubectl config set-context default \ --cluster=kubernetes-training \ --user=system:node:k8s-master2 \ --kubeconfig=k8s-master2.kubeconfig kubectl config use-context default --kubeconfig=k8s-master2.kubeconfig
输出文件
1 2 3 ls k8s-master*config k8s-master1.kubeconfig k8s-master2.kubeconfig
k8s-master3节点的配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 kubectl config set-cluster kubernetes-training \ --certificate-authority=ca.pem \ --embed-certs=true \ --server=https://${VIP}:8443 \ --kubeconfig=k8s-master3.kubeconfig kubectl config set-credentials system:node: k8s-master3 \ --client-certificate=k8s-master3.pem \ --client-key=k8s-master3-key.pem \ --embed-certs=true \ --kubeconfig=k8s-master3.kubeconfig kubectl config set-context default \ --cluster=kubernetes-training \ --user=system:node:k8s-master3 \ --kubeconfig=k8s-master3.kubeconfig kubectl config use-context default --kubeconfig=k8s-master3.kubeconfig
输出文件
1 2 ls k8s-master3*config k8s-master3.kubeconfig
k8s-node1节点配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 kubectl config set-cluster kubernetes-training \ --certificate-authority=ca.pem \ --embed-certs=true \ --server=https://${VIP}:8443 \ --kubeconfig=k8s-node1.kubeconfig kubectl config set-credentials system:node: k8s-node1 \ --client-certificate=k8s-node1.pem \ --client-key=k8s-node1-key.pem \ --embed-certs=true \ --kubeconfig=k8s-node1.kubeconfig kubectl config set-context default \ --cluster=kubernetes-training \ --user=system:node:k8s-node1 \ --kubeconfig=k8s-node1.kubeconfig kubectl config use-context default --kubeconfig=k8s-node1.kubeconfig
输出文件
1 2 ls k8s-node1*config k8s-node1.kubeconfig
kube-proxy配置文件 为kube-proxy服务生成kubeconfig配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 kubectl config set-cluster kubernetes-training \ --certificate-authority=ca.pem \ --embed-certs=true \ --server=https://${VIP}:8443 \ --kubeconfig=kube-proxy.kubeconfig kubectl config set-credentials system: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-training \ --user=system:kube-proxy \ --kubeconfig=kube-proxy.kubeconfig kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
输出文件
1 2 ls kube-proxy*config kube-proxy.kubeconfig
kube-controller-manager配置文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 kubectl config set-cluster kubernetes-training \ --certificate-authority=ca.pem \ --embed-certs=true \ --server=https://${VIP}:8443 \ --kubeconfig=kube-controller-manager.kubeconfig kubectl config set-credentials system:kube- controller-manager \ --client-certificate=kube-controller-manager.pem \ --client-key=kube-controller-manager-key.pem \ --embed-certs=true \ --kubeconfig=kube-controller-manager.kubeconfig kubectl config set-context default \ --cluster=kubernetes-training \ --user=system:kube-controller-manager \ --kubeconfig=kube-controller-manager.kubeconfig kubectl config use-context default --kubeconfig=kube-controller-manager.kubeconfig
输出文件
1 2 ls kube-con *configkube-controller-manager.kubeconfig
kube-scheduler配置文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 kubectl config set-cluster kubernetes-training \ --certificate-authority=ca.pem \ --embed-certs=true \ --server=https://${VIP}:8443 \ --kubeconfig=kube-scheduler.kubeconfig kubectl config set-credentials system:kube- scheduler \ --client-certificate=kube-scheduler.pem \ --client-key=kube-scheduler-key.pem \ --embed-certs=true \ --kubeconfig=kube-scheduler.kubeconfig kubectl config set-context default \ --cluster=kubernetes-training \ --user=system:kube-scheduler \ --kubeconfig=kube-scheduler.kubeconfig kubectl config use-context default --kubeconfig=kube-scheduler.kubeconfig
输出文件
1 2 ls kube-sch*config kube-scheduler.kubeconfig
Admin配置文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 kubectl config set-cluster kubernetes-training \ --certificate-authority=ca.pem \ --embed-certs=true \ --server=https://${VIP}:8443 \ --kubeconfig=admin.kubeconfig kubectl config set-credentials admin \ --client-certificate=admin.pem \ --client-key=admin-key.pem \ --embed-certs=true \ --kubeconfig=admin.kubeconfig kubectl config set-context default \ --cluster=kubernetes-training \ --user=admin \ --kubeconfig=admin.kubeconfig kubectl config use-context default --kubeconfig=admin.kubeconfig
输出文件
1 2 ls ad*config admin.kubeconfig
配置和生成密钥 Kubernetes 存储了集群状态、应用配置和密钥等很多不同的数据。而 Kubernetes 也支持集群数据的加密存储。
本部分将会创建加密密钥以及一个用于加密 Kubernetes Secrets 的 加密配置文件。
所有操作主节点执行
加密密钥 建立加密密钥:
1 ENCRYPTION_KEY=$(head -c 32 / dev / urandom | base64 )
加密配置文件 生成名为 encryption-config.yaml 的加密配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 cat > encryption-config.yaml <<EOF kind : EncryptionConfig apiVersion : v1 resources : - resources: - secrets providers : - aescbc: keys : - name: key1 secret : ${ENCRYPTION_KEY} - identity: {} EOF
分发证书文件 将 kubelet 与 kube-proxy kubeconfig 配置文件复制到每个 worker 节点上:
创建配置文件目录
1 2 3 4 5 6 for host in k8s-master1 k8s-master2 k8s-master3 k8s-node1 ; do ssh root@$host "mkdir -p \ /opt/cni/bin \ /var /lib/kubelet \ /var /lib/kube-proxy \ /var /lib/kubernetes \ /var /run /kubernetes " ; done
将 admin、kube-controller-manager 与 kube-scheduler kubeconfig 配置文件复制到每个控制节点上:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 分发文件方法一; scp ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \ service-account-key.pem service-account.pem \ encryption-config.yaml \ kube-controller-manager.kubeconfig kube-scheduler.kubeconfig k8s-master1:/var/ lib/kubernetes/ scp admin.kubeconfig k8s-master1:~/ scp ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \ service-account-key.pem service-account.pem \ encryption-config.yaml \ kube-controller-manager.kubeconfig kube-scheduler.kubeconfig k8s-master2:/var/ lib/kubernetes/ scp ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \ service-account-key.pem service-account.pem \ encryption-config.yaml \ kube-controller-manager.kubeconfig kube-scheduler.kubeconfig k8s-master3:/var/ lib/kubernetes/ 分发文件方法二; for NODE in k8s-master1 k8s-master2 k8s-master3; do echo "-----$NODE------" scp ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \ service-account-key.pem service-account.pem \ encryption-config.yaml \ kube-controller-manager.kubeconfig kube-scheduler.kubeconfig $NODE :/var/ lib/kubernetes/ ; done scp k8s-master1-key.pem k8s-master1.pem k8s-master1:/var/ lib/kubelet/ scp k8s-master1.kubeconfig k8s-master1:/var/ lib/kubelet/ kubeconfig scp kube-proxy.kubeconfig k8s-master1:/var/ lib/kube-proxy/ kubeconfig scp kube-proxy.pem k8s-master1:/var/ lib/kube-proxy/ scp kube-proxy-key.pem k8s-master1:/var/ lib/kube-proxy/ scp kube-controller-manager-key.pem k8s-master1:/var/ lib/kubernetes/ kube-controller-manager-key.pem scp kube-controller-manager.pem k8s-master1:/var/ lib/kubernetes/ scp kube-scheduler.pem k8s-master1:/var/ lib/kubernetes/ kube-scheduler.pem scp kube-scheduler-key.pem k8s-master1:/var/ lib/kubernetes/ scp k8s-master2-key.pem k8s-master2.pem k8s-master2:/var/ lib/kubelet/ scp k8s-master2.kubeconfig k8s-master2:/var/ lib/kubelet/ kubeconfig scp kube-proxy.kubeconfig k8s-master2:/var/ lib/kube-proxy/ kubeconfig scp kube-proxy-key.pem k8s-master2:/var/ lib/kube-proxy/ scp kube-proxy.pem k8s-master2:/var/ lib/kube-proxy/ scp kube-controller-manager-key.pem k8s-master2:/var/ lib/kubernetes/ kube-controller-manager-key.pem scp kube-controller-manager.pem k8s-master2:/var/ lib/kubernetes/ scp kube-scheduler.pem k8s-master2:/var/ lib/kubernetes/ kube-scheduler.pem scp kube-scheduler-key.pem k8s-master2:/var/ lib/kubernetes/ scp k8s-master3-key.pem k8s-master3.pem k8s-master3:/var/ lib/kubelet/ scp k8s-master3.kubeconfig k8s-master3:/var/ lib/kubelet/ kubeconfig scp kube-proxy.kubeconfig k8s-master3:/var/ lib/kube-proxy/ kubeconfig scp kube-proxy-key.pem k8s-master3:/var/ lib/kube-proxy/ scp kube-proxy.pem k8s-master3:/var/ lib/kube-proxy/ scp kube-controller-manager-key.pem k8s-master3:/var/ lib/kubernetes/ kube-controller-manager-key.pem scp kube-controller-manager.pem k8s-master3:/var/ lib/kubernetes/ scp kube-scheduler.pem k8s-master3:/var/ lib/kubernetes/ kube-scheduler.pem scp kube-scheduler-key.pem k8s-master3:/var/ lib/kubernetes/ scp ca.pem k8s-node1:/var/ lib/kubernetes/ scp k8s-node1-key.pem k8s-node1.pem k8s-node1:/var/ lib/kubelet/ scp k8s-node1.kubeconfig k8s-node1:/var/ lib/kubelet/ kubeconfig scp kube-proxy.kubeconfig k8s-node1:/var/ lib/kube-proxy/ kubeconfig scp kube-proxy-key.pem k8s-node1:/var/ lib/kube-proxy/ scp kube-proxy.pem k8s-node1:/var/ lib/kube-proxy/
kubernetes的组件都是无状态的,所有集群的状态都存储在etcd集群中
部署etcd集群 etcd目录结构
软件包解压目录
/usr/local/etcd/src/
ssl证书申请文件
/usr/local/etcd/json
ssl证书文件
/usr/local/etcd/ssl/
可执行文件
/usr/local/etcd/bin/
工作目录
/usr/local/etcd/data/
etcd的目录在生成证书的最后已经全部创建 并且证书文件也全部拷贝完成
下载etcd二进制包并解压 1 2 3 cd wget https://gi thub.com/etcd-io/ etcd/releases/ download/v3.4.1/ etcd-v3.4.1 -linux-amd64.tar.gz tar -zxvf etcd-v3.4.1 -linux-amd64.tar.gz -C /usr/ local/etcd/ src/
复制可执行文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 复制方法一; scp -p /usr/ local/etcd/ src/etcd-v3.4.1-linux-amd64/ etcd k8s-master1:/usr/ local/etcd/ bin/ scp -p /usr/ local/etcd/ src/etcd-v3.4.1-linux-amd64/ etcdctl k8s-master1:/usr/ local/etcd/ bin/ scp -p /usr/ local/etcd/ src/etcd-v3.4.1-linux-amd64/ etcd k8s-master2:/usr/ local/etcd/ bin/ scp -p /usr/ local/etcd/ src/etcd-v3.4.1-linux-amd64/ etcdctl k8s-master2:/usr/ local/etcd/ bin/ scp -p /usr/ local/etcd/ src/etcd-v3.4.1-linux-amd64/ etcd k8s-master3:/usr/ local/etcd/ bin/ scp -p /usr/ local/etcd/ src/etcd-v3.4.1-linux-amd64/ etcdctl k8s-master2:/usr/ local/etcd/ bin/ 复制方法二; for host in k8s-master1 k8s-master2 k8s-master3; do echo "----$host----" scp -p /usr/ local/etcd/ src/etcd-v3.4.1-linux-amd64/ etcd* $host :/usr/ local/etcd/ bin/; ssh $host "ln -s /usr/local/etcd/bin/* /usr/bin/" ; done 或者直接复制执行文件到 /usr/ bin,这里方便管理复制到/usr/ local/etcd/ bin下
设置etcd系统服务文件 在/etc/systemd/system/目录下导入文件etcd.service
配置master节点的配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 配置master1的etcd cat << EOF | tee /etc/ systemd/system/ etcd.service [Unit] Description=Etcd Server Documentation=https:// coreos.com/etcd/ docs/latest/ After=network.target After=network-online.target Wants=network-online.target [Service] Type=notify Restart=on-failure LimitNOFILE=65536 ExecStart=/usr/ local/etcd/ bin/etcd \\ --name=etcd00 \\ --data-dir=/usr/ local/etcd/ data/ \\ --listen-peer-urls=https:// $MASTER1_IP :2380 \\ --listen-client-urls=https:// $MASTER1_IP :2379 ,https:// 127.0 .0.1 :2379 \\ --advertise-client-urls=https:// $MASTER1_IP :2379 \\ --initial-advertise-peer-urls=https:// $MASTER1_IP :2380 \\ --initial-cluster=etcd00=https:// $MASTER1_IP :2380 ,etcd01=https:// $MASTER2_IP :2380 ,etcd02=https:// $MASTER3_IP :2380 \\ --initial-cluster-token=etcd-cluster \\ --initial-cluster-state=new \\ --cert-file=/usr/ local/etcd/ ssl/etcd.pem \\ --key-file=/usr/ local/etcd/ ssl/etcd-key.pem \\ --peer-cert-file=/usr/ local/etcd/ ssl/etcd.pem \\ --peer-key-file=/usr/ local/etcd/ ssl/etcd-key.pem \\ --trusted-ca-file=/usr/ local/etcd/ ssl/ca.pem \\ --peer-trusted-ca-file=/usr/ local/etcd/ ssl/ca.pem [Install] WantedBy=multi-user.target EOF 配置master2的etcd cat << EOF | tee /etc/ systemd/system/ etcd2.service [Unit] Description=Etcd Server Documentation=https:// coreos.com/etcd/ docs/latest/ After=network.target After=network-online.target Wants=network-online.target [Service] Type=notify Restart=on-failure LimitNOFILE=65536 ExecStart=/usr/ local/etcd/ bin/etcd \\ --name=etcd01 \\ --data-dir=/usr/ local/etcd/ data/ \\ --listen-peer-urls=https:// $MASTER2_IP :2380 \\ --listen-client-urls=https:// $MASTER2_IP :2379 ,https:// 127.0 .0.1 :2379 \\ --advertise-client-urls=https:// $MASTER2_IP :2379 \\ --initial-advertise-peer-urls=https:// $MASTER2_IP :2380 \\ --initial-cluster=etcd00=https:// $MASTER1_IP :2380 ,etcd01=https:// $MASTER2_IP :2380 ,etcd02=https:// $MASTER3_IP :2380 \\ --initial-cluster-token=etcd-cluster \\ --initial-cluster-state=new \\ --cert-file=/usr/ local/etcd/ ssl/etcd.pem \\ --key-file=/usr/ local/etcd/ ssl/etcd-key.pem \\ --peer-cert-file=/usr/ local/etcd/ ssl/etcd.pem \\ --peer-key-file=/usr/ local/etcd/ ssl/etcd-key.pem \\ --trusted-ca-file=/usr/ local/etcd/ ssl/ca.pem \\ --peer-trusted-ca-file=/usr/ local/etcd/ ssl/ca.pem [Install] WantedBy=multi-user.target EOF scp /etc/ systemd/system/ etcd2.service k8s-master2:/etc/ systemd/system/ etcd.service rm -rf /etc/ systemd/system/ etcd2.service 配置master3的etcd cat << EOF | tee /etc/ systemd/system/ etcd3.service [Unit] Description=Etcd Server Documentation=https:// coreos.com/etcd/ docs/latest/ After=network.target After=network-online.target Wants=network-online.target [Service] Type=notify Restart=on-failure LimitNOFILE=65536 ExecStart=/usr/ local/etcd/ bin/etcd \\ --name=etcd02 \\ --data-dir=/usr/ local/etcd/ data/ \\ --listen-peer-urls=https:// $MASTER3_IP :2380 \\ --listen-client-urls=https:// $MASTER3_IP :2379 ,https:// 127.0 .0.1 :2379 \\ --advertise-client-urls=https:// $MASTER3_IP :2379 \\ --initial-advertise-peer-urls=https:// $MASTER3_IP :2380 \\ --initial-cluster=etcd00=https:// $MASTER1_IP :2380 ,etcd01=https:// $MASTER2_IP :2380 ,etcd02=https:// $MASTER3_IP :2380 \\ --initial-cluster-token=etcd-cluster \\ --initial-cluster-state=new \\ --cert-file=/usr/ local/etcd/ ssl/etcd.pem \\ --key-file=/usr/ local/etcd/ ssl/etcd-key.pem \\ --peer-cert-file=/usr/ local/etcd/ ssl/etcd.pem \\ --peer-key-file=/usr/ local/etcd/ ssl/etcd-key.pem \\ --trusted-ca-file=/usr/ local/etcd/ ssl/ca.pem \\ --peer-trusted-ca-file=/usr/ local/etcd/ ssl/ca.pem [Install] WantedBy=multi-user.target EOF scp /etc/ systemd/system/ etcd3.service k8s-master3:/etc/ systemd/system/ etcd.service rm -rf /etc/ systemd/system/ etcd3.service
配置选项
选项说明
wal
存放预写式日志,文件中记录了整个数据变化的全部历程,数据的修改在提交前,都要先写入到WAL中
data-dir
指定节点的数据存储目录(包括:节点ID、集群ID、集群初始化配置、Snapshot文件等),如果未指定,会写在当前目录
wal-dir
存放预写式日志,文件中记录了整个数据变化的全部历程,数据的修改在提交前,都要先写入到WAL中,如果未指定,写在–data-dir目录下面
name
节点名称,如果–initial-cluster-state=new这个值为new,哪么–name的参数值必须位于–initial-cluster列表中
cert-file
客户端与服务器之间TLS证书文件的路径
key-file
客户端与服务器之间TLS密钥文件的路径
trusted-ca-file
签名client证书的CA证书,用于验证client证书
peer-cert-file
对等服务器TLS证书文件的路径
peer-key-file
对等服务器TLS密钥文件的路径
peer-client-cert-auth
启用对等客户端证书验证
client-cert-auth
启用客户端验证
listen-peer-urls
与集群其它成员之间的通信地址
initial-advertise-peer-urls
通告给集群其它节点,本地的对等URL地址
listen-client-urls
监听本地端口,对外提供服务的地址
advertise-client-urls
客户端URL,用于通告集群的其余部分
initial-cluster-token
集群的token,整个集群中保持一致
initial-cluster
集群中的所有信息节点
initial-cluster-state
初始化集群状态,默认为new
auto-compaction-mode
配置基于时间的三种模式
auto-compaction-retention
设置保留历史时间为1小时
max-request-bytes
服务器将接受的最大客户端请求大小
quota-backend-bytes
当后端大小超过给定的配额时,报警
heartbeat-interval
心跳间隔的时间,单位毫秒
election-timeout
选举超时时间,单位毫秒
所有节点启动etcd服务并设置为开机自启 1 2 3 4 5 6 7 8 9 10 11 启动服务方法一(每台单独执行); systemctl daemon-reload && systemctl enable etcd.service && systemctl restart etcd.service & 启动服务方法二(master1执行); for NODE in k8s-master1 k8s-master2 k8s-master3; do echo "--- $NODE ---" ssh $NODE "systemctl daemon-reload" ssh $NODE "systemctl enable --now etcd" & done wait
如果有某一台节点启动失败 请手动启动
1 2 3 4 5 6 7 8 9 systemctl daemon-reload systemctl restart etcd.service for NODE in k8s-master1 k8s-master2 k8s-master3; do echo "--- $NODE ---" ssh $NODE "systemctl daemon-reload" ssh $NODE "systemctl start etcd" & done wait
检查etcd集群状态 三个节点的IP
1 2 3 4 5 6 etcdctl \ --cacert=/usr/ local/etcd/ ssl/ca.pem \ --cert=/usr/ local/etcd/ ssl/etcd.pem \ --key=/usr/ local/etcd/ ssl/etcd-key.pem \ --endpoints="https://200.200.100.71:2379,\ https://200.200.100.72:2379,https://200.200.100.73:2379" endpoint health
输出信息
1 2 https ://200.200.100.71:2379 is healthy: successfully committed proposal: took = 14 .100152 mshttps ://200.200.100.72:2379 is healthy: successfully committed proposal: took = 29 .074303 ms
全部节点为healthy 表明etcd集群搭建成功
部署keepalived+HAProxy 1.信息可以按照自己的环境填写,或者和我相同
2.网卡名称都为eth0,如有不相同建议修改下面配置,或者直接修改centos7网卡为eth0
3.cluster dns或domain有改变的话,需要修改kubelet-conf.yml
HA(haproxy+keepalived) 单台master就不要用HA了
首先所有master安装haproxy+keeplived
1 2 3 4 for NODE in k8s-master1 k8s-master2 k8s-master3; do echo "--- $NODE ---" ssh $NODE 'yum install haproxy keepalived -y' & done
安装完记得检查 (是每台master进行检查)
1 2 3 4 5 for NODE in k8s-master1 k8s-master2 k8s-master3;do echo "--- $NODE ---" ssh $NODE "rpm -qa|grep haproxy" ssh $NODE "rpm -qa|grep keepalived" done
在k8s-master1修改配置文件,并分发给其他master
· haproxy配置文件修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 cat << EOF | tee /etc/haproxy/haproxy.cfg global log 127.0.0.1 local2 chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon defaults mode tcp log global retries 3 timeout connect 10s timeout client 1m timeout server 1m frontend kubernetes bind *:8443 mode tcp option tcplog default_backend kubernetes-apiserver backend kubernetes-apiserver mode tcp balance roundrobin server k8s-master1 200.200.100.71:6443 check maxconn 2000 server k8s-master2 200.200.100.72:6443 check maxconn 2000 server k8s-master3 200.200.100.73:6443 check maxconn 2000 EOF
#在最后一行修改或者添加我们的master节点,端口默认是8443、这里更改了默认端口
· keeplived配置文件修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 cat << EOF | tee /etc/keepalived/keepalived.conf global_defs { router_id LVS_DEVEL } vrrp_script check_haproxy { script "/etc/keepalived/check_haproxy.sh" interval 3 fall 10 timeout 9 rise 2 } vrrp_instance VI_1 { state MASTER interface ens18 virtual_router_id 51 priority 100 advert_int 1 mcast_src_ip 200.200 .100.71 nopreempt authentication { auth_type PASS auth_pass 1111 } unicast_peer { 200.200 .100.72 200.200 .100.73 } virtual_ipaddress { 200.200 .100.70 } track_script { check_haproxy } } EOF
另外keepalived需要修改
1 2 3 router_id LVS_DEVEL_1 修改为不同 state BACKUP 备用priority 101 优先级需要修改
#unicast_peer 为master节点IP
#virtual_ipaddress 为VIP地址,自行修改
#interface 物理网卡地址
添加keeplived健康检查脚本
1 2 3 4 5 6 7 8 cat > /etc/keepalived/check_haproxy.sh <<EOF #!/bin/bash A=\`ps -C haproxy --no-header | wc -l\` if [ \$A -eq 0 ];then systemctl stop keepalived fi EOF chmod +x /etc/keepalived/check_haproxy.sh
##注意修改VIP地址
分发keeplived及haproxy文件给所有master
# 分发文件
1 2 3 4 5 6 for NODE in k8s-master1 k8s-master2 k8s-master3; do echo "--- $NODE ---" scp -r /etc/ haproxy/haproxy.cfg $NODE:/ etc/haproxy/ scp -r /etc/ keepalived/keepalived.conf $NODE:/ etc/keepalived/ scp -r /etc/ keepalived/check_haproxy.sh $NODE:/ etc/keepalived/ done
ping下vip看看能通否,先等待大概四五秒等keepalived和haproxy起来
ping 200.200.100.70
这里的70是我们漂移IP (VIP)
如果vip没起来就是keepalived没起来就每个节点上去restart下keepalived或者确认下配置文件/etc/keepalived/keepalived.conf里网卡名和ip是否注入成功
1 2 3 4 5 6 7 for NODE in k8s-master1 k8s-master2 k8s-master3; do echo "--- $NODE ---" ssh $NODE 'systemctl enable --now haproxy keepalived' ssh $NODE 'systemctl restart haproxy keepalived' done systemctl status keepalived systemctl status haproxy
部署master节点 注意 本文所有操作均在master节点执行 本文主要介绍kubernetes master组件的安装
附 v1.17.3版本软件包的下载地址
1 https:// dl.k8s.io/v1.17.3/ kubernetes-server-linux-amd64.tar.gz
本部分将会在控制节点上部署 Kubernetes 控制服务。每个控制节点上需要部署的服务包括:Kubernetes API Server、Scheduler 以及 Controller Manager 等。
下载并安装kubernetes组件可执行文件 kubectl 文件已经下载过了 可以选择不下载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 wget --timestamping \ "https://storage.googleapis.com/kubernetes-release/release/v1.17.3/bin/linux/amd64/kube-apiserver" \ "https://storage.googleapis.com/kubernetes-release/release/v1.17.3/bin/linux/amd64/kube-controller-manager" \ "https://storage.googleapis.com/kubernetes-release/release/v1.17.3/bin/linux/amd64/kube-scheduler" \ "https://storage.googleapis.com/kubernetes-release/release/v1.17.3/bin/linux/amd64/kubectl" chmod +x kube-apiserver kube-controller-manager kube-scheduler kubectl 解压缩 tar -zxvf /root/ kubernetes-server-1.17 .3 -linux-amd64.tar.gz --strip-components=3 -C /usr/ local/bin kubernetes/ server/bin/ kube{let,ctl,-apiserver,-controller-manager,-scheduler,-proxy} for host in k8s-master1 k8s-master2 k8s-master3; do echo "---$host---" cd /usr/ local/bin/ scp kube{let,ctl,-apiserver,-controller-manager,-scheduler,-proxy} $host :/usr/ local/bin/ done scp /usr/ local/bin/ kube{let,-proxy} k8s-node1:/usr/ local/bin/
使kubectl命令可以使用table键
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 source /usr/share/bash-completion/bash_completion source <(kubectl completion bash) cat > /var/lib/kubernetes/audit-policy.yaml <<EOF apiVersion : audit.k8s.io/v1beta1 kind : Policy rules : - level: None resources : - group: "" resources : - endpoints - services - services/status users : - 'system:kube-proxy' verbs : - watch - level: None resources : - group: "" resources : - nodes - nodes/status userGroups : - 'system:nodes' verbs : - get - level: None namespaces : - kube-system resources : - group: "" resources : - endpoints users : - 'system:kube-controller-manager' - 'system:kube-scheduler' - 'system:serviceaccount:kube-system:endpoint-controller' verbs : - get - update - level: None resources : - group: "" resources : - namespaces - namespaces/status - namespaces/finalize users : - 'system:apiserver' verbs : - get - level: None resources : - group: metrics.k8s.io users : - 'system:kube-controller-manager' verbs : - get - list - level: None nonResourceURLs : - '/healthz*' - /version - '/swagger*' - level: None resources : - group: "" resources : - events - level: Request omitStages : - RequestReceived resources : - group: "" resources : - nodes/status - pods/status users : - kubelet - 'system:node-problem-detector' - 'system:serviceaccount:kube-system:node-problem-detector' verbs : - update - patch - level: Request omitStages : - RequestReceived resources : - group: "" resources : - nodes/status - pods/status userGroups : - 'system:nodes' verbs : - update - patch - level: Request omitStages : - RequestReceived users : - 'system:serviceaccount:kube-system:namespace-controller' verbs : - deletecollection - level: Metadata omitStages : - RequestReceived resources : - group: "" resources : - secrets - configmaps - group: authentication.k8s.io resources : - tokenreviews - level: Request omitStages : - RequestReceived resources : - group: "" - group: admissionregistration.k8s.io - group: apiextensions.k8s.io - group: apiregistration.k8s.io - group: apps - group: authentication.k8s.io - group: authorization.k8s.io - group: autoscaling - group: batch - group: certificates.k8s.io - group: extensions - group: metrics.k8s.io - group: networking.k8s.io - group: policy - group: rbac.authorization.k8s.io - group: scheduling.k8s.io - group: settings.k8s.io - group: storage.k8s.io verbs : - get - list - watch - level: RequestResponse omitStages : - RequestReceived resources : - group: "" - group: admissionregistration.k8s.io - group: apiextensions.k8s.io - group: apiregistration.k8s.io - group: apps - group: authentication.k8s.io - group: authorization.k8s.io - group: autoscaling - group: batch - group: certificates.k8s.io - group: extensions - group: metrics.k8s.io - group: networking.k8s.io - group: policy - group: rbac.authorization.k8s.io - group: scheduling.k8s.io - group: settings.k8s.io - group: storage.k8s.io - level: Metadata omitStages : - RequestReceived EOF
拷贝配置文件到其他master节点
1 2 3 4 for host in k8s-master2 k8s-master3; do echo "---$host---" scp /var/lib/kubernetes/audit-policy.yaml $host :/var/lib/kubernetes/audit-policy .yaml done
生成kube-apiserver.service配置启动文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 cat <<EOF | sudo tee /etc/systemd/system/kube-apiserver.service [Unit] Description =Kubernetes API Server Documentation =https://github.com/kubernetes/kubernetes[Service] ExecStart =/usr/local/bin/kube-apiserver \\ --advertise-address =$VIP \\ --default-not-ready-toleration-seconds =360 \\ --default-unreachable-toleration-seconds =360 \\ --feature-gates =DynamicAuditing=true \\ --max-mutating-requests-inflight =2000 \\ --max-requests-inflight =4000 \\ --default-watch-cache-size =200 \\ --delete-collection-workers =2 \\ --encryption-provider-config =/var/lib/kubernetes/encryption-config.yaml \\ --etcd-cafile =/usr/local/etcd/ssl/ca.pem \\ --etcd-certfile =/usr/local/etcd/ssl/etcd.pem \\ --etcd-keyfile =/usr/local/etcd/ssl/etcd-key.pem \\ --etcd-servers =https://$MASTER1_IP:2379,https://$MASTER2_IP:2379,https://$MASTER3_IP:2379 \\ --bind-address =0.0.0.0 \\ --secure-port =6443 \\ --tls-cert-file =/var/lib/kubernetes/kubernetes.pem \\ --tls-private-key-file =/var/lib/kubernetes/kubernetes-key.pem \\ --insecure-port =0 \\ --audit-dynamic-configuration \\ --audit-log-maxage =15 \\ --audit-log-maxbackup =3 \\ --audit-log-maxsize =100 \\ --audit-log-truncate-enabled \\ --audit-log-path =/var/log/audit.log \\ --audit-policy-file =/var/lib/kubernetes/audit-policy.yaml \\ --profiling \\ --anonymous-auth =false \\ --client-ca-file =/var/lib/kubernetes/ca.pem \\ --enable-bootstrap-token-auth \\ --requestheader-allowed-names ="aggregator" \\ --requestheader-client-ca-file =/var/lib/kubernetes/ca.pem \\ --requestheader-extra-headers-prefix ="X-Remote-Extra-" \\ --requestheader-group-headers =X-Remote-Group \\ --requestheader-username-headers =X-Remote-User \\ --service-account-key-file =/var/lib/kubernetes/service-account.pem \\ --authorization-mode =Node,RBAC \\ --runtime-config =api/all=true \\ --enable-admission-plugins =NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota \\ --allow-privileged =true \\ --apiserver-count =3 \\ --event-ttl =168h \\ --kubelet-certificate-authority =/var/lib/kubernetes/ca.pem \\ --kubelet-client-certificate =/var/lib/kubernetes/kubernetes.pem \\ --kubelet-client-key =/var/lib/kubernetes/kubernetes-key.pem \\ --kubelet-https =true \\ --kubelet-timeout =10s \\ --proxy-client-cert-file =/var/lib/kube-proxy/kube-proxy.pem \\ --proxy-client-key-file =/var/lib/kube-proxy/kube-proxy-key.pem \\ --service-cluster-ip-range =10.250.0.0/16 \\ --service-node-port-range =30000-32767 \\ --logtostderr =true \\ --v =2 Restart =on-failureRestartSec =5[Install] WantedBy =multi-user.targetEOF
拷贝配置文件到另外节点
1 2 scp /etc/ systemd/system/ kube-apiserver.service k8s-master2:/etc/ systemd/system/ scp /etc/ systemd/system/ kube-apiserver.service k8s-master3:/etc/ systemd/system/
配置详解如下
配置选项
选项说明
–advertise-address
向集群成员通知 apiserver 消息的 IP 地址,这个地址必须能够被集群中其他成员访问,如果 IP 地址为空,将会使用 –bind-address,如果未指定 –bind-address,将会使用主机的默认接口地址
–default-not-ready-toleration-seconds
表示 notReady状态的容忍度秒数:默认情况下,NoExecute 被添加到尚未具有此容忍度的每个 Pod 中
–default-unreachable-toleration-seconds
表示 unreachable状态的容忍度秒数:默认情况下,NoExecute 被添加到尚未具有此容忍度的每个 Pod 中
–feature-gates=DynamicAuditing=true
用于实验性质的特性开关组,每个key=value表示
–max-mutating-requests-inflight=2000
在给定时间内进行中可变请求的最大数量,当超过该值时,服务将拒绝所有请求,0 值表示没有限制(默认值 200)
–max-requests-inflight=4000
在给定时间内进行中不可变请求的最大数量,当超过该值时,服务将拒绝所有请求,0 值表示没有限制。(默认值 400)
–default-watch-cache-size=200
默认监视缓存大小,0 表示对于没有设置默认监视大小的资源,将禁用监视缓存
–delete-collection-workers=2
用于 DeleteCollection 调用的工作者数量,这被用于加速 namespace 的清理( 默认值 1)
–encryption-provider-config
将Secret数据加密存储到etcd中的配置文件
–etcd-cafile
用于etcd 通信的 SSL CA 文件
–etcd-certfile
用于 etcd 通信的的 SSL 证书文件
–etcd-keyfile
用于 etcd 通信的 SSL 密钥文件 .
–etcd-servers
连接的 etcd 服务器列表 , 形式为(scheme://ip:port),使用逗号分隔
–bind-address
监听 –seure-port 的 IP 地址,被关联的接口必须能够被集群其它节点和 CLI/web 客户端访问,如果为空,则将使用所有接口(0.0.0.0)
–secure-port=6443
用于监听具有认证授权功能的 HTTPS 协议的端口,默认值是6443
–tls-cert-file
包含用于 HTTPS 的默认 x509 证书的文件,(如果有 CA 证书,则附加于 server 证书之后),如果启用了 HTTPS 服务,并且没有提供 –tls-cert-file 和 –tls-private-key-file,则将为公共地址生成一个自签名的证书和密钥并保存于 /var/run/kubernetes 目录中
–tls-private-key-file
包含匹配 –tls-cert-file 的 x509 证书私钥的文件
–insecure-port=0
监听不安全端口,默认值是8080,设置为0,表示禁用不安全端口
–audit-dynamic-configuration
动态审计配置
–audit-log-maxage=15
基于文件名中的时间戳,旧审计日志文件的最长保留天数
–audit-log-maxbackup=3
旧审计日志文件的最大保留个数
–audit-log-maxsize=100
审计日志被轮转前的最大兆字节数
–audit-log-truncate-enabled
是否启用事件和batch截断功能。
–audit-log-path
如果设置,表示所有到apiserver的请求都会记录到这个文件中,‘-’表示写入标准输出
–audit-policy-file
定义审计策略配置文件的路径,需要打开 ‘AdvancedAuditing’ 特性开关,AdvancedAuditing 需要一个配置来启用审计功能
–profiling
在 web 接口 host:port/debug/pprof/ 上启用 profiling(默认值 true)
–anonymous-auth
启用到 API server 的安全端口的匿名请求,未被其他认证方法拒绝的请求被当做匿名请求,匿名请求的用户名为 system:anonymous,用户组名为 system:unauthenticated(默认值 true)
–client-ca-file
如果设置此标志,对于任何请求,如果存包含 client-ca-file 中的 authorities 签名的客户端证书,将会使用客户端证书中的 CommonName 对应的身份进行认证
–enable-bootstrap-token-auth
启用此选项以允许 ‘kube-system’ 命名空间中的 ‘bootstrap.kubernetes.io/token’ 类型密钥可以被用于 TLS 的启动认证
–requestheader-allowed-names
使用 –requestheader-username-headers 指定的,允许在头部提供用户名的客户端证书通用名称列表。如果为空,任何通过 –requestheader-client-ca-file 中 authorities 验证的客户端证书都是被允许的
–requestheader-client-ca-file
在信任请求头中以 –requestheader-username-headers 指示的用户名之前,用于验证接入请求中客户端证书的根证书捆绑
–requestheader-extra-headers-prefix=“X-Remote-Extra-”
用于检查的请求头的前缀列表,建议使用 X-Remote-Extra-
–requestheader-group-headers=X-Remote-Group
用于检查群组的请求头列表,建议使用 X-Remote-Group
–requestheader-username-headers=X-Remote-User
用于检查用户名的请求头列表,建议使用 X-Remote-User
–service-account-key-file
包含 PEM 加密的 x509 RSA 或 ECDSA 私钥或公钥的文件,用于验证 ServiceAccount 令牌,如果设置该值,–tls-private-key-file 将会被使用,指定的文件可以包含多个密钥,并且这个标志可以和不同的文件一起多次使用
–authorization-mode=Node,RBAC
在安全端口上进行权限验证的插件的顺序列表,以逗号分隔的列表,包括:AlwaysAllow,AlwaysDeny,ABAC,Webhook,RBAC,Node.(默认值 “AlwaysAllow”)
–runtime-config=api/all=true
传递给 apiserver 用于描述运行时配置的键值对集合
–enable-admission-plugins=NodeRestriction
资源限制的相关配置
–allow-privileged=true
如果为 true, 将允许特权容器
–apiserver-count=3
集群中运行的 apiserver 数量,必须为正数(默认值 1
–event-ttl=168h
事件驻留时间(默认值 1h0m0s)
–kubelet-certificate-authority
证书 authority 的文件路径
–kubelet-client-certificate
用于 TLS 的客户端证书文件路径
–kubelet-client-key
用于 TLS 的客户端证书密钥文件路径
–kubelet-https=true
为 kubelet 启用 https(默认值 true)
–kubelet-timeout=10s
kubelet 操作超时时间(默认值5秒)
–proxy-client-cert-file
当必须调用外部程序时,用于证明 aggregator 或者 kube-apiserver 的身份的客户端证书,包括代理到用户 api-server 的请求和调用 webhook 准入控制插件的请求,它期望这个证书包含一个来自于 CA 中的 –requestheader-client-ca-file 标记的签名,该 CA 在 kube-system 命名空间的 ‘extension-apiserver-authentication’ configmap 中发布,从 Kube-aggregator 收到调用的组件应该使用该 CA 进行他们部分的双向 TLS 验证
–proxy-client-key-file
当必须调用外部程序时,用于证明 aggregator 或者 kube-apiserver 的身份的客户端证书密钥。包括代理到用户 api-server 的请求和调用 webhook 准入控制插件的请求
–service-cluster-ip-range
Service网络地址分配 ,CIDR 表示的 IP 范围,服务的 cluster ip 将从中分配, 一定不要和分配给 nodes 和 pods 的 IP 范围产生重叠
–service-node-port-range
Service使用的端口范围
–logtostderr=true
输出日志到标准错误控制台,不输出到文件
–v=2
指定输出日志的级别
生成kube-controller-manager.service 配置启动文件 kube-controller-manager(k8s控制器管理器)是一个守护进程,它通过kube-apiserver监视集群的共享状态(kube-apiserver收集或监视到的一些集群资源状态,供kube-controller-manager或其它客户端watch), 控制器管理器并尝试将当前的状态向所定义的状态迁移(移动、靠近),它本身是有状态的,会修改集群状态信息,如果多个控制器管理器同时生效,则会有一致性问题,所以kube-controller-manager的高可用,只能是主备模式,而kubernetes集群是采用租赁锁实现leader选举,需要在启动参数中加入–leader-elect=true。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 cat <<EOF | sudo tee /etc/systemd/system/kube-controller-manager.service [Unit] Description =Kubernetes Controller ManagerDocumentation =https://github.com/kubernetes/kubernetes[Service] ExecStart =/usr/local/bin/kube-controller-manager \\ --profiling \\ --cluster-name =kubernetes \\ --controllers =*,bootstrapsigner,tokencleaner \\ --kube-api-qps =1000 \\ --kube-api-burst =2000 \\ --leader-elect \\ --use-service-account-credentials\\ --concurrent-service-syncs =2 \\ --bind-address =0.0.0.0 \\ --secure-port =10257 \\ --tls-cert-file =/var/lib/kubernetes/kube-controller-manager.pem \\ --tls-private-key-file =/var/lib/kubernetes/kube-controller-manager-key.pem \\ --port =10252 \\ --authentication-kubeconfig =/var/lib/kubernetes/kube-controller-manager.kubeconfig \\ --client-ca-file =/var/lib/kubernetes/ca.pem \\ --requestheader-client-ca-file =/var/lib/kubernetes/ca.pem \\ --requestheader-extra-headers-prefix ="X-Remote-Extra-" \\ --requestheader-group-headers =X-Remote-Group \\ --requestheader-username-headers =X-Remote-User \\ --authorization-kubeconfig =/var/lib/kubernetes/kube-controller-manager.kubeconfig \\ --cluster-signing-cert-file =/var/lib/kubernetes/ca.pem \\ --cluster-signing-key-file =/var/lib/kubernetes/ca-key.pem \\ --experimental-cluster-signing-duration =876000h \\ --horizontal-pod-autoscaler-sync-period =10s \\ --concurrent-deployment-syncs =10 \\ --concurrent-gc-syncs =30 \\ --node-cidr-mask-size =24 \\ --service-cluster-ip-range =10.250.0.0/16 \\ --pod-eviction-timeout =6m \\ --terminated-pod-gc-threshold =10000 \\ --root-ca-file =/var/lib/kubernetes/ca.pem \\ --service-account-private-key-file =/var/lib/kubernetes/service-account-key.pem \\ --kubeconfig =/var/lib/kubernetes/kube-controller-manager.kubeconfig \\ --logtostderr =true \\ --v =2 Restart =on-failureRestartSec =5[Install] WantedBy =multi-user.targetEOF
原第22行出问题的配置项
1 --requestheader-allowed-names ="" \\
拷贝配置文件到另外节点
1 2 scp /etc/ systemd/system/ kube-controller-manager.service k8s-master2:/etc/ systemd/system/ scp /etc/ systemd/system/ kube-controller-manager.service k8s-master3:/etc/ systemd/system/
配置详解
配置选项
选项说明
–profiling
通过web界面启动分析接口,host:port/debug/pprof/
–cluster-name=kubernetes
集群名称,默认是kubernetes
–controllers=*,bootstrapsigner,tokencleaner
*是启用默认启用所有控制器,但bootstrapsigner,tokencleaner 这两个控制器默认是禁用的,需要人为指定启用
–kube-api-qps=1000
与kube-apiserver通信时的QPS
–kube-api-burst=2000
与kube-apiserver通信时使用
–leader-elect
高可用时启用选举功能
–use-service-account-credentials
如果为true,为每个控制器使用单独的service account
–concurrent-service-syncs=2
允许同时同步Service数量,数字越大,服务管理响应越快,同时消耗更多的CPU和网络资源;
–bind-address=0.0.0.0
监控地址
–secure-port=10257
提供HTTPS服务,默认端口为10257,如果为0,不提供https服务
–tls-cert-file
指定x509证书文件,如果启用了HTTPS服务,但是 –tls-cert-file和–tls-private-key-file 未提供,则会为公共地址生成自签名证书和密钥,并将其保存到–cert-dir指定的目录中。
–tls-private-key-file
指定与–tls-cert-file对应的私钥
–port=10252
提供HTTP服务,不认证,如果设置0,不提供HTTP服务,默认值是10252
–authentication-kubeconfig
kube-controller-kube-controller-manager也是kube-apiserver的客户端,也可以使用kubeconfig方式访问kube-apiserver,
–client-ca-file
启用客户端证书认证
–requestheader-allowed-names=“aggregator”
允许通过的客户端证书Common Name列表,可以提供 –requestheader-username-headers 中的 Header 的用户名。如果为空,则所有通过–requestheader-client-ca-file校验的都允许通过
–requestheader-client-ca-file=/etc/kubernetes/cert/ca.pem
针对收到的请求,在信任–requestheader-username-header指定的header里包含的用户名之前,验证客户端证书的根证书
–requestheader-extra-headers-prefix=“X-Remote-Extra-”
要检查的请求头前缀列表,建议使用 X-Remote-Extra-
–requestheader-group-headers=X-Remote-Group
请求头中需要检查的组名
–requestheader-username-headers=X-Remote-User
请求头中需要检查的用户名
–authorization-kubeconfig=/etc/kubernetes/kube-controller-manager.kubeconfig
指定kubeconfig配置文件路径
–cluster-signing-cert-file=/etc/kubernetes/cert/ca.pem
指定用于集群签发的所有集群范围内证书文件(根证书文件)
–cluster-signing-key-file=/etc/kubernetes/cert/ca-key.pem
指定集群签发证书的key
–experimental-cluster-signing-duration=876000h
证书签发时间
–horizontal-pod-autoscaler-sync-period=10s
HPA控制器检查周期
–concurrent-deployment-syncs=10
允许并发同步的Deployment对象的数量,更大的数量等于更快的部署响应
–concurrent-gc-syncs=30
允许并发同步的垃圾收集器数量。默认值20
–node-cidr-mask-size=24
node节点的CIDR掩码,默认是24
–service-cluster-ip-range=10.254.0.0/16
集群Services 的CIDR范围
–pod-eviction-timeout=6m
在失败节点删除Pod的宽限期,默认是300秒
–terminated-pod-gc-threshold=10000
在Pod垃圾收集器开始删除终止Pod前,允许存在终止的Pod数量,默认是12500
–root-ca-file=/etc/kubernetes/cert/ca.pem
如果设置,该根证书权限将包含service acount的toker secret,这必须是一个有效的PEM编码CA 包
–service-account-private-key-file=/etc/kubernetes/cert/ca-key.pem
包含用于签署service account token的PEM编码RSA或者ECDSA私钥的文件名
–kubeconfig=/etc/kubernetes/kube-controller-manager.kubeconfig
指定kubeconfig配置文件
–logtostderr=true
错误日志到标准输出,而不是文件
–v=2
日志级别
1 控制器管理器管理控制器,各个控制器负责监视(watch)apiserver暴露的集群状态,并不断地尝试把当前状态向所期待的状态迁移;
配置使用kubeconfig访问kube-apiserver安全端口;
默认非安全端口10252,安全端口10257;
kube-controller-manager 3节点高可用,去竞争锁,成为leader;
生成kube-scheduler.service配置启动文件 kube-scheduler作为kubemaster核心组件运行在master节点上面,主要是watch kube-apiserver中未被调度的Pod,如果有,通过调度算法找到最适合的节点Node,然后通过kube-apiserver以对象(pod名称、Node节点名称等)的形式写入到etcd中来完成调度,kube-scheduler的高可用与kube-controller-manager一样,需要使用选举的方式产生。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 for host in k8s-master1 k8s-master2 k8s-master3; do echo "---$host---" ssh $host "mkdir /etc/kubernetes/config/ -p" done cat <<EOF | sudo tee /etc/ kubernetes/config/ kube-scheduler.yaml apiVersion: kubescheduler.config.k8s.io/v1alpha1 kind: KubeSchedulerConfiguration bindTimeoutSeconds: 600 clientConnection: burst: 200 kubeconfig: "/var/lib/kubernetes/kube-scheduler.kubeconfig" qps: 100 enableContentionProfiling: false enableProfiling: true hardPodAffinitySymmetricWeight: 1 healthzBindAddress: 127.0 .0.1 :10251 leaderElection: leaderElect: true metricsBindAddress: $MASTER1_IP:10251 EOF cat <<EOF | tee /etc/ systemd/system/ kube-scheduler.service [Unit] Description =Kubernetes SchedulerDocumentation=https: [Service] ExecStart=/usr/ local/bin/ kube-scheduler \\ --config=/etc/ kubernetes/config/ kube-scheduler.yaml \\ --bind-address=$MASTER1_IP \\ --secure-port=10259 \\ --port=10251 \\ --tls-cert-file =/var/ lib/kubernetes/ kube-scheduler.pem \\ --tls-private -key-file =/var/ lib/kubernetes/ kube-scheduler-key.pem \\ --authentication-kubeconfig=/var/ lib/kubernetes/ kube-scheduler.kubeconfig \\ --client-ca-file =/var/ lib/kubernetes/ ca.pem \\ --requestheader-allowed-names="aggregator" \\ --requestheader-client-ca-file =/var/ lib/kubernetes/ ca.pem \\ --requestheader-extra-headers-prefix="X-Remote-Extra-" \\ --requestheader-group -headers=X-Remote-Group \\ --requestheader-username-headers=X-Remote-User \\ --authorization-kubeconfig=/var/ lib/kubernetes/ kube-scheduler.kubeconfig \\ --logtostderr=true \\ --v=2 Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target EOF
拷贝配置文件到另外节点并修改其配置!!!
1 2 3 4 5 6 scp /etc/ kubernetes/config/ kube-scheduler.yaml k8s-master2:/etc/ kubernetes/config/ scp /etc/ systemd/system/ kube-scheduler.service k8s-master2:/etc/ systemd/system/ scp /etc/ kubernetes/config/ kube-scheduler.yaml k8s-master3:/etc/ kubernetes/config/ scp /etc/ systemd/system/ kube-scheduler.service k8s-master3:/etc/ systemd/system/
启动参数详解
配置选项
选项说明
–config=/etc/kubernetes/kube-scheduler.yaml
配置文件的路径
–bind-address=
监控地址
–secure-port=10259
监听的安全端口,设置为0,不提供安全端口
–port=10251
监听非安全端口,设置为0,不提供非安全端口
–tls-cert-file=/etc/kubernetes/cert/kube-scheduler.pem
包含默认的 HTTPS x509 证书的文件,(CA证书(如果有)在服务器证书之后并置),如果启用了 HTTPS 服务,并且未提供 –tls-cert-file 和 –tls-private-key-file,则会为公共地址生成一个自签名证书和密钥,并将其保存到 –cert-dir 指定的目录中
–tls-private-key-file=/etc/kubernetes/cert/kube-scheduler-key.pem
包含与 –tls-cert-file 匹配的默认 x509 私钥的文件
–authentication-kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig
指定kube-scheduler做为kube-apiserver客户端时使用kubeconfig文件
–client-ca-file=/etc/kubernetes/cert/ca.pem
如果已设置,由 client-ca-file 中的授权机构签名的客户端证书的任何请求都将使用与客户端证书的 CommonName 对应的身份进行身份验证
–requestheader-allowed-names=“aggregator”
客户端证书通用名称列表允许在 –requestheader-username-headers 指定的头部中提供用户名。如果为空,则允许任何由权威机构 –requestheader-client-ca-file 验证的客户端证书。
–requestheader-client-ca-file=/etc/kubernetes/cert/ca.pem
在信任 –requestheader-username-headers 指定的头部中的用户名之前用于验证传入请求上的客户端证书的根证书包。警告:通常不依赖于传入请求已经完成的授权。
–requestheader-extra-headers-prefix=“X-Remote-Extra-”
要检查请求头部前缀列表。建议使用 X-Remote-Extra-
–requestheader-group-headers=X-Remote-Group
用于检查组的请求头部列表。建议使用 X-Remote-Group
–requestheader-username-headers=X-Remote-User
用于检查用户名的请求头部列表。X-Remote-User 很常见。
–authorization-kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig
指向具有足够权限以创建 subjectaccessreviews.authorization.k8s.io 的 ‘core’ kubernetes 服务器的 kubeconfig 文件,这是可选的,如果为空,则禁止所有未经授权跳过的请求
–logtostderr=true
日志记录到标准错误而不是文件
–v=2
日志级别详细程度的数字
kube-scheduler提供非安全端口10251, 安全端口10259;
kube-scheduler 部署3节点高可用,通过选举产生leader;
它监视kube-apiserver提供的watch接口,它根据预选和优选策略两个环节找一个最佳适配,然后调度到此节点;
启动各组件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 for host in k8s-master1 k8s-master2 k8s-master3; do echo "---$host ---" ssh $host "systemctl daemon-reload" ssh $host "systemctl enable --now kube-apiserver kube-controller-manager kube-scheduler" done for host in k8s-master1 k8s-master2 k8s-master3; do echo "---$host ---" ssh $host "systemctl daemon-reload" ssh $host "systemctl restart kube-apiserver kube-controller-manager kube-scheduler" done for host in k8s-master1 k8s-master2 k8s-master3; do echo "---$host ---" ssh $host "systemctl daemon-reload" ssh $host "systemctl stop kube-apiserver kube-controller-manager kube-scheduler" done
请等待10秒以便 kubernetes api server初始化
1 2 3 systemctl status kube-apiserver systemctl status kube-controller-manager systemctl status kube-scheduler
拷贝admin 的kubeconfig 为kubectl默认读取的.kube/config 1 2 3 4 5 6 cd for host in k8s-master1 k8s-master2 k8s-master3; do echo "---$host---" ssh $host "mkdir /root/.kube -p" scp /root/ ssl/kubernetes/ admin.kubeconfig $host :/root/ .kube/config done
查看集群信息
输出信息
1 2 3 Kubernetes master is running at https://127.0 .0 .1 :8443 To further debug and diagnose cluster problems, use 'kubectl cluster-info dump' .
查看 cs信息
输出信息
1 2 3 4 5 6 NAME STATUS MESSAGE ERRORcontroller -manager Healthy ok scheduler Healthy ok etcd -1 Healthy {"health" :"true" } etcd -0 Healthy {"health" :"true" } etcd -2 Healthy {"health" :"true" }
Kubelet RBAC 授权 注意 本文所有操作均在master节点执行 本节将会配置 API Server 访问 Kubelet API 的 RBAC 授权。访问 Kubelet API 是获取 metrics、日志以及执行容器命令所必需的。
所有操作均在主节点操作
这里设置 Kubeket –authorization-mode 为 Webhook 模式。Webhook 模式使用 SubjectAccessReview API 来决定授权。 创建 system:kube-apiserver-to-kubelet ClusterRole 以允许请求 Kubelet API 和执行大部分来管理 Pods 的任务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 cd /root/ssl/kubernetes cat <<EOF | kubectl apply --kubeconfig admin.kubeconfig -f - apiVersion : rbac.authorization.k8s.io/v1beta1 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 verbs : - "*" EOF
输出信息
1 clusterrole.rbac.authorization .k8s.io/system :kube-apiserver-to -kubelet created
Kubernetes API Server 使用客户端凭证授权 Kubelet 为 kubernetes 用户,此凭证用 –kubelet-client-certificate flag 来定义。
绑定 system:kube-apiserver-to-kubelet ClusterRole 到 kubernetes 用户:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 cat <<EOF | kubectl apply --kubeconfig admin.kubeconfig -f - apiVersion : rbac.authorization.k8s.io/v1beta1 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
输出信息
1 clusterrolebinding.rbac .authorization .k8s .io/system:kube-apiserver created
部署node节点 注意 本文所有操作所有节点执行 本部分将会部署 Kubernetes 工作节点。每个节点上将会安装以下服务: container networking plugins kubelet kube-proxy
安装依赖 安装 OS 依赖组件:
1 2 3 4 for host in k8s-master1 k8s-master2 k8s-master3 k8s-node1;do echo "---$host ---" ssh $host "yum install -y socat conntrack ipset" ; done
socat 命令用于支持 kubectl port-forward 命令。
下载worker 二进制文件
1 wget https://gi thub.com/containernetworking/ plugins/releases/ download/v0.8.2/ cni-plugins-linux-amd64-v0.8.2 .tgz
解压cni插件
1 2 3 4 5 6 7 tar -zxvf cni-plugins-linux-amd64-v0.8.2 .tgz -C /opt/ cni/bin/ for host in k8s-master2 k8s-master3 k8s-node1; do echo "---$host---" ssh $host "mkdir /opt/cni/bin/ -p" scp /opt/ cni/bin/ * $host :/opt/ cni/bin/ done
生成kubelet.service systemd服务文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 cat << EOF | sudo tee /etc/systemd/system/kubelet.service [Unit] Description =Kubernetes KubeletDocumentation =https://github.com/kubernetes/kubernetesAfter =docker.serviceRequires =docker.service[Service] ExecStart =/usr/local/bin/kubelet \\ --config =/var/lib/kubelet/kubelet-config.yaml \\ --image-pull-progress-deadline =2m \\ --kubeconfig =/var/lib/kubelet/kubeconfig \\ --pod-infra-container-image =cargo.caicloud.io/caicloud/pause-amd64:3.1 \\ --network-plugin =cni \\ --register-node =true \\ --v =2 \\ --container-runtime =docker \\ --container-runtime-endpoint =unix:///var/run/dockershim.sock \\ --image-pull-progress-deadline =15m Restart =on-failureRestartSec =5[Install] WantedBy =multi-user.targetEOF
拷贝启动文件到其他节点
1 2 3 4 for host in k8s-master2 k8s-master3 k8s-node1; do echo "---$host---" scp /etc/ systemd/system/ kubelet.service $host :/etc/ systemd/system/ done
配置参数详解
配置选项
选项说明
–bootstrap-kubeconfig
指定令牌认证文件
–cert-dir
设置kube-controller-manager生成证书和私钥的目录
–cni-conf-dir=
指定cni配置文件目录
–container-runtime=docker
指定容器运行时引擎
–container-runtime-endpoint=
监听的unix socket位置(Windows上面为 tcp 端口)。
–root-dir=
kubelet 保存数据的目录,默认:/var/lib/kubelet
–kubeconfig=
kubelet作为客户端使用的kubeconfig认证文件,此文件是由kube-controller-mananger生成的
–config=
指定kubelet配置文件
–hostname-override=
用来配置该节点在集群中显示的主机名,kubelet设置了-–hostname-override参数后,kube-proxy也需要设置,否则会出现找不到Node的情况
–pod-infra-container-image=
每个pod中的network/ipc 名称空间容器将使用的镜像
–image-pull-progress-deadline=
镜像拉取进度最大时间,如果在这段时间拉取镜像没有任何进展,将取消拉取,默认:1m0s
–volume-plugin-dir=
第三方卷插件的完整搜索路径,默认:”/usr/libexec/kubernetes/kubelet-plugins/volume/exec/“
–logtostderr=true
日志记录到标准错误而不是文件
–v=2
日志级别详细程度的数字
master1节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 cat <<EOF | sudo tee /var/lib/kubelet/kubelet-config.yaml kind: KubeletConfiguration apiVersion: kubelet.config.k8s.io/v1beta1 authentication: anonymous: enabled: false webhook: enabled: true x509: clientCAFile: "/var/lib/kubernetes/ca.pem" authorization: mode: Webhook clusterDomain: "cluster.local" clusterDNS: - "10.250.0.10" runtimeRequestTimeout: "15m" tlsCertFile: "/var/lib/kubelet/k8s-master1.pem" tlsPrivateKeyFile: "/var/lib/kubelet/k8s-master1-key.pem" address: "$MASTER1_IP" staticPodPath: "" syncFrequency: 1m fileCheckFrequency: 20s httpCheckFrequency: 20s staticPodURL: "" port: 10250 readOnlyPort: 0 rotateCertificates: true serverTLSBootstrap: true registryPullQPS: 0 registryBurst: 20 eventRecordQPS: 0 eventBurst: 20 enableDebuggingHandlers: true enableContentionProfiling: true healthzPort: 10248 healthzBindAddress: "$MASTER1_IP" nodeStatusUpdateFrequency: 10s nodeStatusReportFrequency: 1m imageMinimumGCAge: 2m imageGCHighThresholdPercent: 85 imageGCLowThresholdPercent: 80 volumeStatsAggPeriod: 1m kubeletCgroups: "" systemCgroups: "" cgroupRoot: "" cgroupsPerQOS: true cgroupDriver: cgroupfs runtimeRequestTimeout: 10m hairpinMode: promiscuous-bridge maxPods: 220 podCIDR: "10.244.0.0/16" podPidsLimit: -1 resolvConf: /etc/resolv.conf maxOpenFiles: 1000000 kubeAPIQPS: 1000 kubeAPIBurst: 2000 serializeImagePulls: false evictionHard: memory.available: "100Mi" nodefs.available: "10%" nodefs.inodesFree: "5%" imagefs.available: "15%" evictionSoft: {}enableControllerAttachDetach: true failSwapOn: true containerLogMaxSize: 20Mi containerLogMaxFiles: 10 systemReserved: {}kubeReserved: {}systemReservedCgroup: "" kubeReservedCgroup: "" enforceNodeAllocatable: ["pods" ]EOF
master2节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 cat << EOF | sudo tee /var/lib/kubelet/k8s-master2.yaml kind: KubeletConfiguration apiVersion: kubelet.config.k8s.io/v1beta1 authentication: anonymous: enabled: false webhook: enabled: true x509: clientCAFile: "/var/lib/kubernetes/ca.pem" authorization: mode: Webhook clusterDomain: "cluster.local" clusterDNS: - "10.250.0.10" runtimeRequestTimeout: "15m" tlsCertFile: "/var/lib/kubelet/k8s-master2.pem" tlsPrivateKeyFile: "/var/lib/kubelet/k8s-master2-key.pem" address: "$MASTER2_IP" staticPodPath: "" syncFrequency: 1m fileCheckFrequency: 20s httpCheckFrequency: 20s staticPodURL: "" port: 10250 readOnlyPort: 0 rotateCertificates: true serverTLSBootstrap: true registryPullQPS: 0 registryBurst: 20 eventRecordQPS: 0 eventBurst: 20 enableDebuggingHandlers: true enableContentionProfiling: true healthzPort: 10248 healthzBindAddress: "$MASTER2_IP" nodeStatusUpdateFrequency: 10s nodeStatusReportFrequency: 1m imageMinimumGCAge: 2m imageGCHighThresholdPercent: 85 imageGCLowThresholdPercent: 80 volumeStatsAggPeriod: 1m kubeletCgroups: "" systemCgroups: "" cgroupRoot: "" cgroupsPerQOS: true cgroupDriver: cgroupfs runtimeRequestTimeout: 10m hairpinMode: promiscuous-bridge maxPods: 220 podCIDR: "10.244.0.0/16" podPidsLimit: -1 resolvConf: /etc/resolv.conf maxOpenFiles: 1000000 kubeAPIQPS: 1000 kubeAPIBurst: 2000 serializeImagePulls: false evictionHard: memory.available: "100Mi" nodefs.available: "10%" nodefs.inodesFree: "5%" imagefs.available: "15%" evictionSoft: {}enableControllerAttachDetach: true failSwapOn: true containerLogMaxSize: 20Mi containerLogMaxFiles: 10 systemReserved: {}kubeReserved: {}systemReservedCgroup: "" kubeReservedCgroup: "" enforceNodeAllocatable: ["pods" ]EOF scp /var/lib/kubelet/k8s-master2.yaml k8s-master2:/var/lib/kubelet/kubelet-config.yaml rm -rf /var/lib/kubelet/k8s-master2.yaml
k8s-master3 节点的配置文件 在master主机上写入文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 cat << EOF | sudo tee /var/lib/kubelet/k8s-master3.yaml kind: KubeletConfiguration apiVersion: kubelet.config.k8s.io/v1beta1 authentication: anonymous: enabled: false webhook: enabled: true x509: clientCAFile: "/var/lib/kubernetes/ca.pem" authorization: mode: Webhook clusterDomain: "cluster.local" clusterDNS: - "10.250.0.10" runtimeRequestTimeout: "15m" tlsCertFile: "/var/lib/kubelet/k8s-master3.pem" tlsPrivateKeyFile: "/var/lib/kubelet/k8s-master3-key.pem" address: "$MASTER3_IP" staticPodPath: "" syncFrequency: 1m fileCheckFrequency: 20s httpCheckFrequency: 20s staticPodURL: "" port: 10250 readOnlyPort: 0 rotateCertificates: true serverTLSBootstrap: true registryPullQPS: 0 registryBurst: 20 eventRecordQPS: 0 eventBurst: 20 enableDebuggingHandlers: true enableContentionProfiling: true healthzPort: 10248 healthzBindAddress: "$MASTER3_IP" nodeStatusUpdateFrequency: 10s nodeStatusReportFrequency: 1m imageMinimumGCAge: 2m imageGCHighThresholdPercent: 85 imageGCLowThresholdPercent: 80 volumeStatsAggPeriod: 1m kubeletCgroups: "" systemCgroups: "" cgroupRoot: "" cgroupsPerQOS: true cgroupDriver: cgroupfs runtimeRequestTimeout: 10m hairpinMode: promiscuous-bridge maxPods: 220 podCIDR: "10.244.0.0/16" podPidsLimit: -1 resolvConf: /etc/resolv.conf maxOpenFiles: 1000000 kubeAPIQPS: 1000 kubeAPIBurst: 2000 serializeImagePulls: false evictionHard: memory.available: "100Mi" nodefs.available: "10%" nodefs.inodesFree: "5%" imagefs.available: "15%" evictionSoft: {}enableControllerAttachDetach: true failSwapOn: true containerLogMaxSize: 20Mi containerLogMaxFiles: 10 systemReserved: {}kubeReserved: {}systemReservedCgroup: "" kubeReservedCgroup: "" enforceNodeAllocatable: ["pods" ]EOF scp /var/lib/kubelet/k8s-master3.yaml k8s-master3:/var/lib/kubelet/kubelet-config.yaml rm -rf /var/lib/kubelet/k8s-master3.yaml
k8s-node1节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 cat << EOF | sudo tee /var/lib/kubelet/k8s-node1.yaml kind: KubeletConfiguration apiVersion: kubelet.config.k8s.io/v1beta1 authentication: anonymous: enabled: false webhook: enabled: true x509: clientCAFile: "/var/lib/kubernetes/ca.pem" authorization: mode: Webhook clusterDomain: "cluster.local" clusterDNS: - "10.250.0.10" runtimeRequestTimeout: "15m" address: "$NODE1_IP" staticPodPath: "" syncFrequency: 1m fileCheckFrequency: 20s httpCheckFrequency: 20s staticPodURL: "" port: 10250 readOnlyPort: 0 rotateCertificates: true serverTLSBootstrap: true registryPullQPS: 0 registryBurst: 20 eventRecordQPS: 0 eventBurst: 20 enableDebuggingHandlers: true enableContentionProfiling: true healthzPort: 10248 healthzBindAddress: "$NODE1_IP" nodeStatusUpdateFrequency: 10s nodeStatusReportFrequency: 1m imageMinimumGCAge: 2m imageGCHighThresholdPercent: 85 imageGCLowThresholdPercent: 80 volumeStatsAggPeriod: 1m kubeletCgroups: "" systemCgroups: "" cgroupRoot: "" cgroupsPerQOS: true cgroupDriver: cgroupfs runtimeRequestTimeout: 10m hairpinMode: promiscuous-bridge maxPods: 220 podCIDR: "10.244.0.0/16" podPidsLimit: -1 resolvConf: /etc/resolv.conf maxOpenFiles: 1000000 kubeAPIQPS: 1000 kubeAPIBurst: 2000 serializeImagePulls: false evictionHard: memory.available: "100Mi" nodefs.available: "10%" nodefs.inodesFree: "5%" imagefs.available: "15%" evictionSoft: {}enableControllerAttachDetach: true failSwapOn: true containerLogMaxSize: 20Mi containerLogMaxFiles: 10 systemReserved: {}kubeReserved: {}systemReservedCgroup: "" kubeReservedCgroup: "" enforceNodeAllocatable: ["pods" ]tlsCertFile: "/var/lib/kubelet/k8s-node1.pem" tlsPrivateKeyFile: "/var/lib/kubelet/k8s-node1-key.pem" EOF scp /var/lib/kubelet/k8s-node1.yaml k8s-node1:/var/lib/kubelet/kubelet-config.yaml rm -rf /var/lib/kubelet/k8s-node1.yaml
配置详解
配置选项
选项说明
address
kubelet 服务监听的地址
staticPodPath: “”
kubelet 会定期的扫描这个文件夹下的YAML/JSON 文件来创建/删除静态Pod,使用kubeadm安装时非常有用
syncFrequency: 1m
同步运行容器和配置之间的最大时间间隔,默认为1m
fileCheckFrequency: 20s
检查新数据配置文件的周期,默认 20s
httpCheckFrequency: 20s
通过 http 检查新数据的周期,默认 20s
staticPodURL: “”
port: 10250
kubelet 服务的端口,默认 10250
readOnlyPort: 0
没有认证/授权的只读 kubelet 服务端口 ,设置为 0 表示禁用,默认 10255
rotateCertificates
远程认证,默认为false
serverTLSBootstrap: true
kubelet安全引导认证,重启 Kubelet,会发现出现了新的 CSR
authentication:
认证方式有以下几种
anonymous:
匿名
enabled: false
值为false
webhook:
webhook的方式
enabled: true
值为true
x509:
x509认证
clientCAFile: “/etc/kubernetes/cert/ca.pem”
集群ca证书
authorization:
授权
mode: Webhook
授权webhook
registryPullQPS
限制每秒拉取镜像个数,设置为 0 表示不限制, 默认 5
registryBurst
仅当 –registry-qps 大于 0 时使用,设置拉取镜像的最大并发数,允许同时拉取的镜像数,不能超过 registry-qps ,默认 10
eventRecordQPS
限制每秒创建的事件数目,设置为0则不限制,默认为5
eventBurst
当–event-qps大于0时,临时允许该事件记录值超过设定值,但不能超过 event-qps 的值,默认10
enableDebuggingHandlers
启用用于日志收集和本地运行容器和命令的服务端端点,默认值:true
enableContentionProfiling
如果启用了 profiling,则启用性能分析锁
healthzPort
本地 healthz 端点的端口,设置为 0 将禁用,默认值:10248
healthzBindAddress
监听healthz 端口的地址
clusterDomain: “cluster.local”
集群域名, kubelet 将配置所有容器除了主机搜索域还将搜索当前域
clusterDNS:
DNS 服务器的IP地址列表
- “10.254.0.2”
指定一个DNS服务器地址
nodeStatusUpdateFrequency: 10s
node节点状态更新上报频率,默认:10s
nodeStatusReportFrequency: 1m
node节点上报自身状态频率,默认:1m
imageMinimumGCAge: 2m
设置镜像最少多久没有被使用才会被清理
imageGCHighThresholdPercent: 85
设置镜像占用磁盘比率最大值,超过此值将执行镜像垃圾回收,默认 85
imageGCLowThresholdPercent: 80
设置镜像占用磁盘比率最小值,低于此值将停止镜像垃圾回收,默认 80
volumeStatsAggPeriod: 1m
指定kubelet计算和缓存所有容器组及卷的磁盘使用量时间间隔,设置为0禁用卷计算,默认:1m
kubeletCgroups: “”
可选的 cgroups 的绝对名称来创建和运行 kubelet
systemCgroups: “”
可选的 cgroups 的绝对名称,用于将未包含在 cgroup 内的所有非内核进程放置在根目录 / 中,修改这个参数需要重启
cgroupRoot: “”
Pods 可选的root cgroup, 这是由container runtime,在最佳工作的基础上处理的,默认值: ‘’,意思是使用container runtime的默认处理
cgroupsPerQOS: true
支持创建QoS cgroup的层级结构,如果是true,最高层级的
cgroupDriver: systemd
Kubelet用来操作主机cgroups的驱动
runtimeRequestTimeout: 10m
除了长时间运行的请求(pull,logs,exec,attach)以外,所有runtime请求的超时时间,当触发超时时,kubelet会取消请求,抛出一个错误并稍后重试,默认值:2m0s
hairpinMode: promiscuous-bridge
Kubelet该怎么设置hairpin promiscuous-bridge.这个参数允许Service的端点试图访问自己的Service。如果网络没有正确配置为 “hairpin” 流量,通常当 kube-proxy 以 iptables 模式运行,并且 Pod 与桥接网络连接时,就会发生这种情况。Kubelet 公开了一个 hairpin-mode 标志,如果 pod 试图访问他们自己的 Service VIP,就可以让 Service 的 endpoints 重新负载到他们自己身上。hairpin-mode 标志必须设置为 hairpin-veth 或者 promiscuous-bridge。
maxPods
当前 kubelet 可以运行的容器组数目,默认:110
podCIDR
pod使用的CIDR网段
podPidsLimit: -1
pod中设置PID限制
resolvConf
用作容器DNS解析配置的解析器配置文件,默认: “/etc/resolv.conf”
maxOpenFiles: 1000000
kubelet 进程可以打开的文件数目,默认:1000000
kubeAPIQPS
与kube-apiserver会话时的QPS,默认:15
kubeAPIBurst
与kube-apiserver会话时的并发数,默认:10
serializeImagePulls: false
禁止一次只拉取一个镜像
evictionHard:
一个清理阈值的集合,达到该阈值将触发一次容器清理
memory.available: “100Mi”
小gf 100Mi时清理
nodefs.available: “10%”
nodefs.inodesFree: “5%”
imagefs.available: “15%”
evictionSoft: {}
清理阈值的集合,如果达到一个清理周期将触发一次容器清理
enableControllerAttachDetach: true
允许附加/分离控制器来管理调度到当前节点的附加/分离卷,并禁用kubelet执行任何附加/分离操作,默认:true
failSwapOn: true
如果在节点上启用了swap,kubelet将启动失败
containerLogMaxSize: 20Mi
容器日志容量最大值
containerLogMaxFiles: 10
容器日志文件数最大值
systemReserved: {}
https://kubernetes.io/zh/docs/tasks/administer-cluster/reserve-compute-resources/,系统守护进程争取资源预留,这里均设置为默认值
kubeReserved: {}
kubernetes 系统守护进程争取资源预留,这里均设置为默认值
systemReservedCgroup: “”
要选择性的在系统守护进程上执行 kube-reserved,需要把 kubelet 的 –kube-reserved-cgroup 标志的值设置为 kube 守护进程的父控制组要想在系统守护进程上可选地执行 system-reserved,请指定 –system-reserved-cgroup kubelet 标志的值为 OS 系统守护进程的父级控制组,这里均设置为默认值
kubeReservedCgroup: “”
要选择性的在系统守护进程上执行 kube-reserved,需要把 kubelet 的 –kube-reserved-cgroup 标志的值设置为 kube 守护进程的父控制组这里均设置为默认值
enforceNodeAllocatable: [“pods”]
无论何时,如果所有 pod 的总用量超过了 Allocatable,驱逐 pod 的措施将被执行
kubelet组件采用主动的查询机制,定期向kube-apiserver获取当前节点应该处理的任务,如果有任务分配到了自己身上(如创建Pod),从而他去处理这些任务;
kubelet暴露了两个端口10248,http形式的healthz服务,另一个是10250,https服务,其实还有一个只读的10255端口,这里是禁用的。
生成kube-proxy 服务启动文件 本文是二进制安装kubernetes v1.17.0 之kube-proxy,kube-proxy是什么,这里就不得不说下service,service是一组Pod的抽象集合,它相当于一组Pod的负载均衡器,负责将请求分发到对应的pod,kube-proxy就是负责service的实现的,当请求到达service时,它通过label关联到后端并转发到某个Pod;kube-proxy提供了三种负载均衡模式:用户空间、iptables、ipvs,网上有很多关于这三种模式的区别,这里先不详述,本文采用ipvs。
kube-proxy需要运行在所有节点上(因为我们master节点也有Pod,如果没有的话,可以只部署在非master节点上),kube-proxy它主动的去监听kube-apiserver中service和endpoint的变化情况,然后根据定义的模式,创建路由规则,并提供服务service IP(headless类型的service无IP)和负载均衡功能。注意:在所有节点安装ipvsadm和ipset命令,加载ip_vs内核模块,准备章节已经执行过。
master节点上操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 cat <<EOF | sudo tee /var/lib/kube-proxy/kube-proxy-config.yaml kind: KubeProxyConfiguration apiVersion: kubeproxy.config.k8s.io/v1alpha1 clientConnection: burst: 200 kubeconfig: "/var/lib/kube-proxy/kubeconfig" qps: 100 bindAddress: $VIP healthzBindAddress: $VIP:10256 metricsBindAddress: $VIP:10249 enableProfiling: true clusterCIDR: 10.244 .0 .0 /16 mode: "ipvs" portRange: "" kubeProxyIPTablesConfiguration: masqueradeAll: false kubeProxyIPVSConfiguration: scheduler: rr excludeCIDRs: [] EOF for host in k8s-master2 k8s-master3;do echo "---$host---" scp /var/lib/kube-proxy/kube-proxy-config.yaml $host:/var/lib/kube-proxy/ done node配置 cat << EOF | sudo tee k8s-node1.yaml kind: KubeProxyConfiguration apiVersion: kubeproxy.config.k8s.io/v1alpha1 clientConnection: burst: 200 kubeconfig: "/var/lib/kube-proxy/kubeconfig" qps: 100 bindAddress: $NODE1_IP healthzBindAddress: $NODE1_IP:10256 metricsBindAddress: $NODE1_IP:10249 enableProfiling: true clusterCIDR: 10.244 .0 .0 /16 mode: "ipvs" portRange: "" kubeProxyIPTablesConfiguration: masqueradeAll: false kubeProxyIPVSConfiguration: scheduler: rr excludeCIDRs: [] EOF scp k8s-node1.yaml k8s-node1:/var/lib/kube-proxy/kube-proxy-config.yaml rm -rf k8s-node1.yaml
配置详解
配置选项
选项说明
clientConnection
与kube-apiserver交互时的参数设置
burst: 200
临时允许该事件记录值超过qps设定值
kubeconfig
kube-proxy 客户端连接 kube-apiserver 的 kubeconfig 文件路径设置
qps: 100
与kube-apiserver交互时的QPS,默认值5
bindAddress
kube-proxy监听地址
healthzBindAddress
用于检查服务的IP地址和端口,默认:0.0.0.0:10256
metricsBindAddress
metrics服务的ip地址和端口,默认:127.0.0.1:10249
enableProfiling
如果设为true,则通过/debug/pprof处理程序上的web界面进行概要分析
clusterCIDR
kube-proxy 根据 –cluster-cidr 判断集群内部和外部流量,指定 –cluster-cidr 或 –masquerade-all 选项后 kube-proxy 才会对访问 Service IP 的请求做 SNAT
hostnameOverride
参数值必须与 kubelet 的值一致,否则 kube-proxy 启动后会找不到该 Node,从而不会创建任何 ipvs 规则;
mode
使用 ipvs 模式
portRange
主机端口的范围(beginPort- endport,单端口或beginPort+偏移量),可用于代理服务流量。如果(未指定,0,或0-0)端口将被随机选择
kubeProxyIPTablesConfiguration:
masqueradeAll: false
如果使用纯iptables代理,SNAT所有通过服务集群ip发送的通信
kubeProxyIPVSConfiguration:
scheduler: rr
当proxy为ipvs模式时,ipvs调度类型
excludeCIDRs: []
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 cat <<EOF | sudo tee /etc/systemd/system/kube-proxy.service [Unit] Description =Kubernetes Kube Proxy Documentation =https://github.com/kubernetes/kubernetes[Service] ExecStart =/usr/local/bin/kube-proxy \\ --config =/var/lib/kube-proxy/kube-proxy-config.yaml \\ --logtostderr =true \\ --v =2 Restart =on-failureRestartSec =5[Install] WantedBy =multi-user.targetEOF
拷贝启动配置文件到其他节点
1 2 3 4 for host in k8s-master2 k8s-master3 k8s-node1; do echo "---$host---" scp /etc/ systemd/system/ kube-proxy.service $host :/etc/ systemd/system/ done
启动worker服务
1 2 3 4 5 6 7 for host in k8s-master1 k8s-master2 k8s-master3 k8s-node1; do echo "---$host ---" ssh $host "systemctl daemon-reload" ssh $host "systemctl enable --now kubelet kube-proxy" done systemctl status kubelet systemctl status kube-proxy
此时所有节点的kubelet启动之后 会自动加入集群
查看集群节点
输出信息
1 2 3 4 5 NAME STATUS ROLES AGE VERSIONk8s -master1 NotReady <none> 9 s v1.17 .3 k8s -master2 NotReady <none> 9 s v1.17 .3 k8s -master3 NotReady <none> 39 m v1.17 .3 k8s -node1 NotReady <none> 39 m v1.17 .3
可以看到 所有的节点都已经成功加入集群
状态显示 NotReady 是因为没有配置网络插件 配置好网络插件就 Ready了
部署网络配置 注意 本文所有操作均在master节点执行 本文主要介绍部署网络 dns 插件
本文的网络插件选用的是calico 以容器的方式运行 本文的dns’插件选用的是coredns以容器的方式运行
安装calico网络 下载calico网络插件的yaml文件
1.16版本的kubernetes calico网络插件应选用3.9及以上的版本
本文选用3.10
1 curl https:// docs.projectcalico.org/v3.10/m anifests/calico.yaml -O
修改网络插件yaml文件内容
1 sed -i 's|192 .168 .0 .0 |10 .244 .0 .0 |' calico .yaml
应用yaml文件
1 kubectl apply -f calico.yaml
查看pod状态
1 kubectl get pods -n kube-system
输出信息
1 2 3 4 5 NAME READY STATUS RESTARTS AGEcalico -kube-controllers-6 d85fdfbd8-8 v2hs 1 /1 Running 0 7 m40scalico -node-984 fd 1 /1 Running 0 7 m40scalico -node-n5kn8 1 /1 Running 0 7 m40scalico -node-q4p7c 1 /1 Running 0 7 m40s
网络插件安装成功
安装coredns插件 先下载jq命令(coredns提供的部署脚本需要使用jq命令对生成的yaml文件进行整理)
1 2 wget https://gi thub.com/stedolan/ jq/releases/ download/jq-1.6/ jq-linux64 -O /usr/ bin/jq chmod a+x /usr/ bin/jq
克隆GitHub仓库
1 2 yum -y install git git clone https://gi thub.com/coredns/ deployment.git
执行
1 2 cd deployment/kubernetes/./deploy.sh -i 10.250.0.10 | kubectl apply -f -
ip为开头写的集群dns的IP
输出信息
1 2 3 4 5 6 serviceaccount/coredns created clusterrole.rbac.authorization.k8s.io/system:coredns created clusterrolebinding.rbac.authorization.k8s.io/system:coredns created configmap/coredns created deployment.apps/coredns created service/kube-dns created
查看pod
1 2 kubectl scale -n kube-system deployment coredns kubectl get pods -n kube-system
输出信息
1 2 3 4 5 6 7 NAME READY STATUS RESTARTS AGEcalico -kube-controllers-6 d85fdfbd8-8 v2hs 1 /1 Running 0 91 mcalico -node-984 fd 1 /1 Running 0 91 mcalico -node-n5kn8 1 /1 Running 0 91 mcalico -node-q4p7c 1 /1 Running 0 91 mcoredns -68567 cdb47-6 j7bb 1 /1 Running 0 5 m31scoredns -68567 cdb47-7 nwcg 1 /1 Running 0 5 m31s
可以看到calico网络和coredns插件都好了
验证 进入pod内部 pingbaidu.com
如果能ping同 则插件部署完毕
安装Ingress-nginx插件 yaml文件
点击上方超链接 将yaml文件的所有内容复制下来 保存到主节点的nginx-ingress.yaml文件内
然后
1 kubectl apply -f nginx-ds.yaml
输出信息
1 2 3 4 5 6 7 8 9 10 namespace/ingress-nginx created configmap/nginx-configuration created configmap/tcp-services created configmap/udp-services created serviceaccount/nginx-ingress-serviceaccount created clusterrole.rbac .authorization .k8s .io/nginx-ingress-clusterrole created role.rbac .authorization .k8s .io/nginx-ingress-role created rolebinding.rbac .authorization .k8s .io/nginx-ingress-role-nisa-binding created clusterrolebinding.rbac .authorization .k8s .io/nginx-ingress-clusterrole-nisa-binding created daemonset.apps/nginx-ingress-controller created
然后查看Pod
1 kubectl get pods -n ingress-nginx -o wide
输出信息 全部为Running即可
1 2 3 4 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESnginx -ingress-controller-8 xzrd 1 /1 Running 0 2 m13s 200.200.100.73 k8s-node <none> <none>nginx -ingress-controller-c84dv 1 /1 Running 0 2 m13s 200.200.100.74 k8s-node1 <none> <none>nginx -ingress-controller-qlpn5 1 /1 Running 0 2 m13s 200.200.100.71 master <none> <none>
Ingress-nginx插件安装完毕
集群部署完毕