Kubernetes 容器集群管理环境 - 完整部署(上篇)

网友投稿 1059 2022-10-20

本站部分文章、图片属于网络上可搜索到的公开信息,均用于学习和交流用途,不能代表睿象云的观点、立场或意见。我们接受网民的监督,如发现任何违法内容或侵犯了您的权益,请第一时间联系小编邮箱jiasou666@gmail.com 处理。

Kubernetes 容器集群管理环境 - 完整部署(上篇)

Kubernetes(通常称为"K8S")是 Google 开源的容器集群管理系统。其设计目标是在主机集群之间提供一个能够自动化部署、可拓展、应用容器可运营的平台。Kubernetes 通常结合 docker 容器工具工作,并且整合多个运行着 docker 容器的主机集群,Kubernetes 不仅仅支 持Docker,还支持Rocket,这是另一种容器技术。Kubernetes 是一个用于容器集群的自动化部署、扩容以及运维的开源平台。通过 Kubernetes, 可以快速有效地响应用户需求:

快速而有预期地部署应用;极速地扩展你的应用;无缝对接新的应用功能;节省资源,优化硬件资源的使用;

Kubernetes 功能特性:

自动化容器部署与复制随时扩展或收缩容器规模组织容器成组,提供容器间的负载均衡快速更新及回滚容器版本提供弹性伸缩,如果某个容器失效就进行替换

Kubernetes 重要组件:

1 Master 组件

Master 节点上面主要由四个模块组成:APIServer、scheduler、controller manager、etcd

APIServer: 负责对外提供 RESTful 的 Kubernetes API 服务,它是系统管理指令的统一入口,任何对资源进行增删改查的操作都要交给APIServer 处理后再提交给 etcd。kubectl(k8s 提供的客户端工具,该工具内部就是对 Kubernetes API 的调用)是直接和 APIServer 交互的。schedule: 它的职责很明确,就是负责调度 pod 到合适的 Node 上。如果把 scheduler 看成一个黑匣子,那么它的输入是 pod 和由多个 Node 组成的列表,输出是 Pod 和一个 Node 的绑定,即将这个 pod 部署到这个 Node 上。Kubernetes 目前提供了调度算法,但是同样也保留了接口,用户可以根据自己的需求定义自己的调度算法。controller manager: 如果说 APIServer 做的是“前台”的工作的话,那 controller manager 就是负责“后台”的。每个资源一般都对应有一个控制器,而 controller manager 就是负责管理这些控制器的。比如我们通过 APIServer 创建一个 pod,当这个 pod 创建成功后,APIServer   的任务就算完成了。而后面保证 Pod 的状态始终和我们预期的一样的重任就由 controller manager 去保证了。etcd: 它是一个高可用的键值存储系统,Kubernetes 使用它来存储各个资源的状态,从而实现了 Restful 的 API。

2Node 组件

每个 Node 节点主要由三个模块组成:kubelet、kube-proxy、runtime。runtime 指的是容器运行环境,目前 Kubernetes 支持 docker 和 rkt 两种容器。

kubelet: Kubelet 是 Master 在每个 Node 节点上面的 agent,是Node   节点上面最重要的模块,它负责维护和管理该 Node 上面的所有容器,但是如果容器不是通过 Kubernetes 创建的,它并不会管理。本质上,它负责使 Pod   得运行状态与期望的状态一致。kube-proxy: 该模块实现了 Kubernetes 中的服务发现和反向代理功能。反向代理方面:kube-proxy 支持 TCP 和 UDP 连接转发,默认基于Round Robin 算法将客户端流量转发到与 service 对应的一组后端  pod。服务发现方面,kube-proxy 使用 etcd 的 watch 机制,监控集群中 service 和 endpoint 对象数据的动态变化,并且维护一个 service 到   endpoint 的映射关系,从而保证了后端 pod 的 IP 变化不会对访问者造成影响。另外 kube-proxy 还支持 session affinity。

3Pod

Pod 是 k8s 进行资源调度的最小单位,每个 Pod 中运行着一个或多个密切相关的业务容器,这些业务容器共享这个 Pause 容器的 IP 和 Volume,我们以这个不易死亡的 Pause 容器作为 Pod 的根容器,以它的状态表示整个容器组的状态。一个 Pod 一旦被创建就会放到 Etcd 中存储,然后由 Master 调度到一个 Node 绑定,由这个 Node 上的 Kubelet 进行实例化。每个 Pod 会被分配一个单独的 Pod IP,Pod IP + ContainerPort 组成了一个 Endpoint。

4Service

Service 其功能使应用暴露,Pods 是有生命周期的,也有独立的 IP 地址,随着 Pods 的创建与销毁,一个必不可少的工作就是保证各个应用能够感知这种变化。这就要提到 Service 了,Service 是 YAML 或 JSON 定义的由 Pods 通过某种策略的逻辑组合。更重要的是,Pods 的独立 IP 需要通过 Service 暴露到网络中。

K8s 集群可以帮助培育出一个组件及工具的生态,帮助减轻在公有云及私有云上运行应用的负担。

搭建 Kubernetes 集群环境有以下三种方式:

1 Minikube 安装方式

Minikube 是一个工具,可以在本地快速运行一个单点的 Kubernetes,尝试Kubernetes 或日常开发的用户使用。但是这种方式仅可用于学习和测试部署,不能用于生产环境。

1 Kubeadm 安装方式

kubeadm 是一个 kubernetes 官方提供的快速安装和初始化拥有最佳实践(best practice)的kubernetes集群的工具,提供kubeadm init和kubeadm join,用于快速部署 Kubernetes 集群。目前 kubeadm 还处于beta 和 alpha 状态,不推荐用在生产环境,但是可以通过学习这种部署方法来体会一些官方推荐的 kubernetes 最佳实践的设计和思想。

kubeadm 的目标是提供一个最小可用的可以通过Kubernetes 一致性测试的集群,所以并不会安装任何除此之外的非必须的 addon。kubeadm 默认情况下并不会安装一个网络解决方案,所以用 kubeadm 安装完之后,需要自己来安装一个网络的插件。所以说,目前的 kubeadm 是不能用于生产环境的

3二进制包安装方式(生产部署的推荐方式)

从官方下载发行版的二进制包,手动部署每个组件,组成 Kubernetes 集群,这种方式符合企业生产环境标准的 Kubernetes 集群环境的安装,可用于生产方式部署。

一一 基础信息

使用 Kubernetes1.14.2,所有节点机操作系统是 Centos7.5。本文档部署中所需 kubernetes 相关安装包和镜像可提前在翻墙服务器上下载,然后同步到   k8s 部署机器上。具体信息如下:

本套 Kubernetes 集群环境版本-  Kubernetes 1.14.2-  Docker 18.09.6-ce-  Etcd 3.3.13-  Flanneld 0.11.0

插件:-  Coredns-  Dashboard-  Metrics-server

镜像仓库:-  harbor(两个仓库相互同步,对外提供统一入口VIP地址)

主要配置策略

kube-apiserver 高可用(Nginx负载层):- 使用 Nginx+Keepalived 实现高可用, VIP1:172.16.60.250;- 关闭非安全端口 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:metrics-server,使用 https 访问 kubelet 安全端口;-  Log:Elasticsearch、Fluend、Kibana;-  Registry  镜像库:Harbor 私有仓库,两个节点相互同步;

kubernetes 集群部署中生成的证书文件如下:

TLS 作用:就是对通讯加密,防止中间人窃听;同时如果证书不信任的话根本就无法与 apiserver 建立连接,更不用提有没有权限向 apiserver 请求指定内容。

RBAC 作用:RBAC 中规定了一个用户或者用户组(subject)具有请求哪些 api 的权限;在配合 TLS 加密的时候,实际上 apiserver 读取客户端证书的 CN 字段作为用户名,读取 O 字段作为用户组。

总之想要与 apiserver 通讯就必须采用由 apiserver CA 签发的证书,这样才能形成信任关系,建立 TLS 连接;另外可通过证书的 CN、O 字段来提供 RBAC 所需用户与用户组。

kubernetes 集群会默认开启 RABC(角色访问控制机制),这里提前了解几个重要概念:

- DRBCK8S 1.6 引进,是让用户能够访问 K8S API 资源的授权方式(不授权就没有资格访问 K8S 的资源)

- 用户K8S有两种用户:User 和 Service Account。其中,User 给用户使用,Service Account 给进程使用,让进程有相关权限。如 Dashboard 就是一个进程,可以创建一个 Service Account 给它使用。

- 角色Role 是一系列权限的集合,例如一个 Role 可包含读取和列出 Pod 的权限(ClusterRole 和 Role 类似,其权限范围是整个集群)

- 角色绑定RoleBinding把角色映射到用户,从而让这些用户拥有该角色的权限(ClusterRoleBinding和RoleBinding类似,可让用户拥有ClusteRole的权限)

- SecretSecret 是一个包含少量敏感信息如密码,令牌或密钥的对象。把这些信息保存在 Secret 对象中,可以在这些信息被使用时加以控制,并可以减低信息泄露的风险。

二 环境初始化准备

Kubernetes 集群部署过程均需要使用 root 账号操作,下面初始化操作在 k8s的 master 和 node 节点上操作。

这里先以 k8s-master01 节点为例,其他节点类似操作。

1 主机名修改

[root@k8s-master01 ~]# hostnamectl set-hostname k8s-master01

如果 DNS 不支持解析主机名称,则需要修改 /etc/hosts 文件,添加主机名和IP 的对应关系:

[root@k8s-master01 ~]# cat >> /etc/hosts <

2 添加 docker 账户

[root@k8s-master01 ~]# useradd -m docker

3无密码 ssh 信任关系

本篇部署文档有很有操作都是在 k8s-master01 节点上执行,然后远程分发文件到其他节点机器上并远程执行命令,所以需要添加该节点到其它节点的 ssh   信任关系。

[root@k8s-master01 ~]# ssh-keygen -t rsa[root@k8s-master01 ~]# cp /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys[root@k8s-master01 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub -p22 root@k8s-master01[root@k8s-master01 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub -p22 root@k8s-master02[root@k8s-master01 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub -p22 root@k8s-master03[root@k8s-master01 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub -p22 root@k8s-node01[root@k8s-master01 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub -p22 root@k8s-node02[root@k8s-master01 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub -p22 root@k8s-node03

以上信任关系设置后,最好手动验证下本节点登陆到其他节点的 ssh 无密码信任关系

4更新 PATH 变量,将可执行文件目录添加到 PATH 环境变量中

将可执行文件目录添加到 PATH 环境变量中

[root@k8s-master01 ~]# echo 'PATH=/opt/k8s/bin:$PATH' >>/root/.bashrc[root@k8s-master01 ~]# source /root/.bashrc

5安装依赖包

[root@k8s-master01 ~]# yum install -y epel-release[root@k8s-master01 ~]# yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget lsof telnet

关闭无关的服务

[root@k8s-master01 ~]# systemctl stop postfix && systemctl disable postfix

6关闭防火墙

在每台机器上关闭防火墙,清理防火墙规则,设置默认转发策略:

[root@k8s-master01 ~]# systemctl stop firewalld[root@k8s-master01 ~]# systemctl disable firewalld[root@k8s-master01 ~]# iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat[root@k8s-master01 ~]# iptables -P FORWARD ACCEPT[root@k8s-master01 ~]# firewall-cmd --statenot running

7关闭 SELinux

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

[root@k8s-master01 ~]# setenforce 0[root@k8s-master01 ~]# sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config

8关闭 swap 分区

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

[root@k8s-master01 ~]# swapoff -a[root@k8s-master01 ~]# sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

9关闭 dnsmasq

linux 系统开启了 dnsmasq 后(如 GUI 环境),将系统 DNS Server 设置为 127.0.0.1,这会导致 docker 容器无法解析域名,需要关闭它 (centos7 系统可能默认没有安装这个服务)

[root@k8s-node01 ~]# systemctl stop dnsmasq[root@k8s-node01 ~]# systemctl disable dnsmasq

10加载内核模块

[root@k8s-master01 ~]# modprobe ip_vs_rr[root@k8s-master01 ~]# modprobe br_netfilter

11优化内核参数

[root@k8s-master01 ~]# cat > kubernetes.conf <

这里需要注意:

必须关闭 tcp_tw_recycle,否则和 NAT 冲突,会导致服务不通;

关闭 IPV6,防止触发 docker BUG;

12设置系统时区

# 调整系统 TimeZone[root@k8s-master01 ~]# timedatectl set-timezone Asia/Shanghai# 将当前的 UTC 时间写入硬件时钟[root@k8s-master01 ~]# timedatectl set-local-rtc 0# 重启依赖于系统时间的服务[root@k8s-master01 ~]# systemctl restart rsyslog[root@k8s-master01 ~]# systemctl restart crond

13设置 rsyslogd 和 systemd journald (每台节点机都要操作)

systemd 的 journald 是 Centos 7 缺省的日志记录工具,它记录了所有系统、内核、Service Unit 的日志。相比 systemd,journald 记录的日志有如下优势:

可以记录到内存或文件系统;(默认记录到内存,对应的位置为    /run/log/jounal);可以限制占用的磁盘空间、保证磁盘剩余空间;可以限制日志文件大小、保存的时间;journald 默认将日志转发给 rsyslog,这会导致日志写了多份,/var/log/messages 中包含了太多无关日志,不方便后续查看,同时也影响系统性能。

[root@k8s-master01 ~]# mkdir /var/log/journal #持久化保存日志的目录[root@k8s-master01 ~]# mkdir /etc/systemd/journald.conf.d[root@k8s-master01 ~]# cat > /etc/systemd/journald.conf.d/99-prophet.conf <

14创建 k8s 相关目录 (每台节点机都要操作)

[root@k8s-master01 ~]# mkdir -p /opt/k8s/{bin,work} /etc/{kubernetes,etcd}/cert

15升级内核 (每台节点机都要操作)

CentOS 7.x 系统自带的3.10.x 内核存在一些 Bugs,导致运行的Docker、Kubernetes 不稳定,例如:

高版本的 docker(1.13 以后) 启用了3.10 kernel实验支持的kernel memory account 功能(无法关闭),当节点压力大如频繁启动和停止容器时会导致 cgroup memory leak;网络设备引用计数泄漏,会导致类似于报错:   "kernel:unregister_netdevice: waiting for eth0 to become free. Usage count = 1";

解决方案如下:

升级内核到 4.4.X 以上;或者,手动编译内核,disable CONFIG_MEMCG_KMEM 特性;或者安装修复了该问题的 Docker 18.09.1 及以上的版本。

但由于 kubelet 也会设置 kmem(它 vendor 了 runc),所以需要重新编译 kubelet 并指定 GOFLAGS="-tags=nokmem";

这里升级内核方法:

[root@k8s-master01 ~]# uname -r3.10.0-862.el7.x86_64[root@k8s-master01 ~]# rpm -Uvh http://elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm

安装完成后检查 /boot/grub2/grub.cfg 中对应内核 menuentry 中是否包含 initrd16 配置,如果没有,再安装一次!

[root@k8s-master01 ~]# yum --enablerepo=elrepo-kernel install -y kernel-lt

设置开机从新内核启动

[root@k8s-master01 ~]# grub2-set-default 0

重启机器

[root@k8s-master01 ~]# init 6

安装内核源文件(在升级完内核并重启机器后执行,也可以不用执行这一步。可选):

[root@k8s-master01 ~]# yum --enablerepo=elrepo-kernel install kernel-lt-devel-$(uname -r) kernel-lt-headers-$(uname -r)[root@k8s-master01 ~]# uname -r4.4.180-2.el7.elrepo.x86_64

或者也可以采用下面升级内核的方法:

# git clone --branch v1.14.1 --single-branch --depth 1 https://github.com/kubernetes/kubernetes# cd kubernetes# KUBE_GIT_VERSION=v1.14.1 ./build/run.sh make kubelet GOFLAGS="-tags=nokmem"# init 6

16关闭 NUMA

[root@k8s-master01 ~]# cp /etc/default/grub{,.bak}[root@k8s-master01 ~]# vim /etc/default/grub .........GRUB_CMDLINE_LINUX="...... numa=off" # 即添加"numa=0ff"内容

重新生成 grub2 配置文件:

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

17变量脚本文件 (这一步很关键)

[root@k8s-master01 ~]# vim /opt/k8s/bin/environment.sh#!/usr/bin/bash# 生成 EncryptionConfig 所需的加密 keyexport ENCRYPTION_KEY=$(head -c 32 /dev/urandom | base64)# 集群中所有节点机器IP数组(master,node,etcd节点)export NODE_ALL_IPS=(172.16.60.241 172.16.60.242 172.16.60.243 172.16.60.244 172.16.60.245 172.16.60.246)# 集群中所有节点IP对应的主机名数组export NODE_ALL_NAMES=(k8s-master01 k8s-master02 k8s-master03 k8s-node01 k8s-node02 k8s-node03)# 集群中所有master节点集群IP数组export NODE_MASTER_IPS=(172.16.60.241 172.16.60.242 172.16.60.243)# 集群中master节点IP对应的主机名数组export NODE_MASTER_NAMES=(k8s-master01 k8s-master02 k8s-master03)# 集群中所有node节点集群IP数组export NODE_NODE_IPS=(172.16.60.244 172.16.60.245 172.16.60.246)# 集群中node节点IP对应的主机名数组export NODE_NODE_NAMES=(k8s-node01 k8s-node02 k8s-node03)# 集群中所有etcd节点集群IP数组export NODE_ETCD_IPS=(172.16.60.241 172.16.60.242 172.16.60.243)# 集群中etcd节点IP对应的主机名数组(这里是和master三节点机器共用)export NODE_ETCD_NAMES=(k8s-etcd01 k8s-etcd02 k8s-etcd03)# etcd 集群服务地址列表export ETCD_ENDPOINTS="https://172.16.60.241:2379,https://172.16.60.242:2379,https://172.16.60.243:2379"# etcd 集群间通信的 IP 和端口export ETCD_NODES="k8s-etcd01=https://172.16.60.241:2380,k8s-etcd02=https://172.16.60.242:2380,k8s-etcd03=https://172.16.60.243:2380"# kube-apiserver 的反向代理(地址端口.这里也就是nginx代理层的VIP地址export KUBE_APISERVER="https://172.16.60.250:8443"# 节点间互联网络接口名称. 这里我所有的centos7节点机的网卡设备是ens192,而不是eth0export IFACE="ens192"# 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

三 创建集群中需要的 CA 证书和秘钥

为确保安全,kubernetes 系统各组件需要使用 x509 证书对通信进行加密和认证。CA (Certificate Authority) 是自签名的根证书,用来签名后续创建的其它证书。这里使用 CloudFlare 的 PKI 工具集 cfssl 创建所有证书。下面部署命令均在k8s-master01节点上执行,然后远程分发文件和执行命令。

1 安装 cfssl 工具集

[root@k8s-master01 ~]# mkdir -p /opt/k8s/cert && cd /opt/k8s[root@k8s-master01 k8s]# wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64[root@k8s-master01 k8s]# mv cfssl_linux-amd64 /opt/k8s/bin/cfssl [root@k8s-master01 k8s]# wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64[root@k8s-master01 k8s]# mv cfssljson_linux-amd64 /opt/k8s/bin/cfssljson [root@k8s-master01 k8s]# wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64[root@k8s-master01 k8s]# mv cfssl-certinfo_linux-amd64 /opt/k8s/bin/cfssl-certinfo [root@k8s-master01 k8s]# chmod +x /opt/k8s/bin/*[root@k8s-master01 k8s]# export PATH=/opt/k8s/bin:$PATH

2创建根证书 (CA)

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

创建配置文件

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

[root@k8s-master01 k8s]# cd /opt/k8s/work[root@k8s-master01 work]# cat > ca-config.json <

配置说明:

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

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

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

创建证书签名请求文件

[root@k8s-master01 work]# cd /opt/k8s/work[root@k8s-master01 work]# cat > ca-csr.json <

配置说明:

CN:Common Name,kube-apiserver 从证书中提取该字段作为请求的用户名 (User Name),浏览器使用该字段验证网站是否合法;

O:Organization,kube-apiserver 从证书中提取该字段作为请求用户所属的组 (Group);

kube-apiserver 将提取的 User、Group 作为 RBAC 授权的用户标识;

生成 CA 证书和私钥

[root@k8s-master01 work]# cd /opt/k8s/work[root@k8s-master01 work]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca[root@k8s-master01 work]# ls ca*ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem[root@k8s-master01 work]#

3分发证书文件

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

[root@k8s-master01 work]# cd /opt/k8s/work[root@k8s-master01 work]# source /opt/k8s/bin/environment.sh[root@k8s-master01 work]# for node_all_ip in ${NODE_ALL_IPS[@]} do echo ">>> ${node_all_ip}" ssh root@${node_all_ip} "mkdir -p /etc/kubernetes/cert" scp ca*.pem ca-config.json root@${node_all_ip}:/etc/kubernetes/cert done

四 部署 kubectl 命令行工具

kubectl 是 kubernetes 集群的命令行管理工具. kubectl 默认从 ~/.kube/config 文件读取kube-apiserver地址和认证信息,如果没有配置,执行kubectl命令时就会报错!kubectl 只需要部署一次,生成的 kubeconfig文件是通用的,可以拷贝到需要执行 kubectl 命令的节点机器,重命名为 ~/.kube/config;这里我将 kubectl 节点只部署到三个 master 节点机器上,其他节点不部署 kubectl 命令。也就是说后续进行 kubectl 命令管理就只能在master 节点上操作。下面部署命令均在 k8s-master01 节点上执行,然后远程分发文件和执行命令。

如果没有部署 kubectl 工具,则执行时会报错说没有该命令:

[root@k8s-master01 ~]# kubectl get pods-bash: kubectl: command not found

1 下载和分发 kubectl 二进制文件

二进制包下载地址:https://pan.baidu.com/s/1HUWFqKVLyxIzoX2LDQSEBg

提取密码:7kaf

[root@k8s-master01 ~]# cd /opt/k8s/work[root@k8s-master01 work]# wget https://dl.k8s.io/v1.14.2/kubernetes-client-linux-amd64.tar.gz[root@k8s-master01 work]# tar -xzvf kubernetes-client-linux-amd64.tar.gz

分发到所有使用 kubectl 的节点,这里只分发到三个 master 节点

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

2创建 admin 证书和私钥

kubectl 与 apiserver https 安全端口通信,apiserver 对提供的证书进行认证和授权。kubectl 作为集群的管理工具,需要被授予最高权限,这里创建具有最高权限的 admin 证书。

创建证书签名请求:

[root@k8s-master01 work]# cd /opt/k8s/work[root@k8s-master01 work]# cat > admin-csr.json <

配置说明:

O为system:masters,kube-apiserver 收到该证书后将请求的 Group 设置为 system:masters;

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

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

生成证书和私钥:

[root@k8s-master01 work]# cd /opt/k8s/work[root@k8s-master01 work]# cfssl gencert -ca=/opt/k8s/work/ca.pem \ -ca-key=/opt/k8s/work/ca-key.pem \ -config=/opt/k8s/work/ca-config.json \ -profile=kubernetes admin-csr.json | cfssljson -bare admin [root@k8s-master01 work]# ls admin*admin.csr admin-csr.json admin-key.pem admin.pem

3创建 kubeconfig 文件

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

[root@k8s-master01 work]# cd /opt/k8s/work[root@k8s-master01 work]# source /opt/k8s/bin/environment.sh

设置集群参数

[root@k8s-master01 work]# kubectl config set-cluster kubernetes \ --certificate-authority=/opt/k8s/work/ca.pem \ --embed-certs=true \ --server=${KUBE_APISERVER} \ --kubeconfig=kubectl.kubeconfig

设置客户端认证参数

[root@k8s-master01 work]# kubectl config set-credentials admin \ --client-certificate=/opt/k8s/work/admin.pem \ --client-key=/opt/k8s/work/admin-key.pem \ --embed-certs=true \ --kubeconfig=kubectl.kubeconfig

设置上下文参数

[root@k8s-master01 work]# kubectl config set-context kubernetes \ --cluster=kubernetes \ --user=admin \ --kubeconfig=kubectl.kubeconfig

设置默认上下文

[root@k8s-master01 work]# 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 文件中(不加时,写入的是证书文件路径,

后续拷贝 kubeconfig 到其它机器时,还需要单独拷贝证书文件,这就很不方便了)

4分发 kubeconfig 文件, 保存的文件名为 ~/.kube/config;

分发到所有使用 kubectl 命令的节点,即分发到三个 master 节点上

[root@k8s-master01 work]# cd /opt/k8s/work[root@k8s-master01 work]# source /opt/k8s/bin/environment.sh[root@k8s-master01 work]# for node_master_ip in ${NODE_MASTER_IPS[@]}do echo ">>> ${node_master_ip}" ssh root@${node_master_ip} "mkdir -p ~/.kube" scp kubectl.kubeconfig root@${node_master_ip}:~/.kube/configdone

出处:http://1t.click/aRcN

未完待续........

上一篇:维业股份:副总裁汪拂晓辞职,张绍娟继任
下一篇:国际观察:假重塑 真维霸 美国“友岸外包”可以休矣
相关文章

 发表评论

暂时没有评论,来抢沙发吧~