前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >天不生Kubernetes,运维万古如长夜|生产级K8s高可用集群实战一

天不生Kubernetes,运维万古如长夜|生产级K8s高可用集群实战一

作者头像
CNCF
发布2020-02-26 13:15:55
1.6K0
发布2020-02-26 13:15:55
举报
文章被收录于专栏:CNCF


Kubernetes解决了诸多运维难题,是目前主流的基础架构平台,也是容器编排领域的事实标准,可谓“天不生Kubernetes,运维万古如长夜”。如此流行的Kubernetes,该如何掌握、又该如何应用到生产中呢?本系列文章会详细讲述。

一 主要技术点

  1. Kubernetes集群介绍
  2. 部署高可用Kubernetes集群
  3. 部署应用程序
  4. 公开应用程序
  5. 更新应用程序
  6. 集群中的日志收集与监控
  7. Istio流量治理
  8. 基于Kubernetes的CI/CD
  9. ...

通过本系列文章,你将能够使用Kubeadm和Binary方式部署高可用的Kubernetes集群,了解集群中的一些名词及概念,在集群上部署容器化应用程序,并调试、扩容、更新、对外发布这些程序,实现流量治理,轻松搞定蓝绿发布、AB测试、金丝雀发布等集群相关功能。

二 Kubernetes集群介绍

Kubernetes协调高度可用的计算机集群,这些计算机作为一个单元连接在一起工作。Kubernetes允许将容器化的应用程序部署到集群中,且不是传统的绑定到单个机器上。为了利用这种新的部署模型,应用程序需要以一种将它们与单个主机分离的方式打包——容器化。在传统的部署模型中,应用程序直接安装到特定的机器上,与主机深度集成,与传统部署模型相比,容器化的应用程序更加灵活可用。Kubernetes以更有效的方式在集群中自动化分发和调度应用程序容器。

Kubernetes集群由两种资源类型组成:Master和Node:

  • Master协调集群工作,组件有:
    • 使用二进制运行Kubernetes集群的时候,在Master上这三个是可选组件
    • kube-apiserver:对外提供操作和获取Kubernetes资源的API,是集群中唯一操作ETCD的组件
    • kube-controller-manager:集群状态的维护者,观察集群的实际状态,并与ETCD中的预期状态进行对比,让两者达到最终一致
    • kube-scheduler:Kubernetes的大脑,调度新应用的发布请求,决策发布在哪些节点上
    • docker、kubelet和kube-proxy
    • 网络插件,本环境使用的calico
  • Node运行应用程序,包含的组件:
    • kubelet:与API Server交互,接收指令、启动Pod、关闭Pod
    • kube-proxy:对Pod进行寻址,实现负载均衡和服务发现
    • docker:Kubernetes集群中的一种容器运行时
    • 网络插件,本环境使用的calico

同时Kubernetes将集群中的网络配置及对象的状态信息存储在ETCD集群中,所以还需要一套ETCD集群。

三 部署高可用Kubernetes集群

Kubernetes集群是一个功能丰富但有些复杂的系统,不过亲自运行一个系统永远是学习它的最佳开始。

本篇文章是该系列文章的开篇,主要介绍Kubernetes高可用集群的两种主流安装方式:Kubeadm和二进制(这两种安装方式各有优劣,至于生产环境中采用何种方式部署集群,亦或是使用云平台提供的Kubernetes集群,还需根据实际情况选择),以及部署Kubernetes的主要插件。

不论是Kubeadm还是二进制的方式安装Kubernetes集群,都要先初始化安装环境。

3.1 安装环境介绍

以下主机列表是我介绍两种安装方式时使用的主要资源:

  1. 操作系统:CentOS7.x
  2. 主机角色: Kubeadm环境主机列表: 主机名IP地址VIPCPU内存角色lb01192.168.0.3192.168.0.111>=1>=2GHaproxyKeepAlive MASTERlb02192.168.0.5192.168.0.111>=1>=2GHaproxyKeepAlive BACKUPkm01192.168.0.11 >=2>=2GMaster/Ansiblekm02192.168.0.12 >=2>=2GMasterkm03192.168.0.13 >=2>=2GMasterkn01192.168.0.21 >=2>=2GNodekn02192.168.0.22 >=2>=2GNode二进制环境主机列表: 主机名IP地址VIPCPU内存角色lb01192.168.0.3192.168.0.111>=1>=2GHaproxyKeepAlive MASTERlb02192.168.0.5192.168.0.111>=1>=2GHaproxyKeepAlive BACKUPkm01.aiops.red192.168.0.16 >=2>=2GMaster/ETCD/Ansiblekm02.aiops.red192.168.0.17 >=2>=2GMaster/ETCDkm03.aiops.red192.168.0.18 >=2>=2GMaster/ETCDkn01.aiops.red192.168.0.23 >=2>=2GNodekn02.aiops.red192.168.0.24 >=2>=2GNode
  3. 软件列表:Kubernetes v1.17.+:包括了Kubernetes集群所有的相关组件ETCD v3.3.18+:存储Kubernetes状态信息 Docker v19.03.4:Kubernetes中的容器运行时,也是1.17.+官方建议的Docker版本 HaProxy:负载均衡器,Kubernetes集群中Kube-apiserver的流量入口和负载均衡 KeepAlived:高可用工具,负责HaProxy的高可用 Ansible:配置管理工具,减少安装Kubernetes高可用集群时机械化的重复工作,减少工作量,但不会影响你对Kubernetes系统的认识

3.2 集群安装前的准备

对Kubernetes集群环境初始化,需要在集群中的各个节点执行大量相同的命令,为了减少机械、廉价的重复性工作,也为了让读者将更多的心思用到Kubernetes高可用集群本身,我这里采用了简单易上手的Ansible配置管理工具进行初始化工作。

3.2.1 安装配置Ansible
  1. 如果你的环境中没有Ansible,可通过以下命令安装。了解Ansible更多用法,可以查阅我的另一篇文章配置管理工具之Ansible:
代码语言:javascript
复制
[root@km01 ~]# yum -y install ansible

# 如果提示没有这个安装包,则需要安装epel-releas源,然后再次安装ansible
[root@km01 ~]# yum -y install epel-release
  1. 配置目标主机,在/etc/ansible/hosts文件中新增三个分组:k8sm组,Kubernetes集群的所有Master;k8sn组:Kubernetes集群中的所有Node;k8sall组:Kubernetes集群中所有主机:
代码语言:javascript
复制
[root@km01 ~]# vim /etc/ansible/hosts
[k8sm]
192.168.0.[11:13]
[k8sn]
192.168.0.[21:22]
[k8sall:children]
k8sm
k8sn
  1. 配置免密登录
代码语言:javascript
复制
[root@km01 ~]# ssh-keygen -t rsa
[root@km01 ~]# ssh-copy-id 192.168.0.11
[root@km01 ~]# ssh-copy-id 192.168.0.12
...
[root@km01 ~]# ssh-copy-id 192.168.0.22
  1. 验证 完成以上配置,就可以通过Ansible管理三个分组中的主机进了。在操作前,可以先验证下配置的正确性:
代码语言:javascript
复制
[root@km01 ~]# ansible k8sall -m ping
3.2.2 集群环境初始化(Kubernetes集群中的主机都要执行)
  1. 修改主机名: 各主机名不能重复,且集群中的主机可以通过主机名互相访问
  2. [root@km01 ~]# hostnamectl set-hostname <hostname> # 以Kubeadm环境的hosts文件举例 [root@km01 ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.0.11 km01 192.168.0.12 km02 192.168.0.13 km03 192.168.0.21 kn01 192.168.0.22 kn02
  3. 设置系统参数
  4. 安装docker及创建daemon.json文件
  5. 修改系统时区为Asia/Shanghai
  6. 关闭swap
  7. 关闭防火墙、关闭selinux、重置iptables
  8. 更新yum源并安装依赖包

2-7步均通过Ansible Playbook实现,Playbook文件我已上传到GitHub,囿于篇幅,这里就不再展开文件内容。项目地址 https://github.com/weiwendi/k8sdeploy,把k8sdeploy项目拉取到ansible所在的主机上:

代码语言:javascript
复制
[root@km01 ~]# git clone https://github.com/weiwendi/k8sdeploy.git
[root@km01 ~]# cd k8sdeploy/initialize
[root@km01 initialize]# ansible-playbook installPackages.yaml
[root@km01 initialize]# ansible-playbook initEnv.yaml

执行完这两个脚本,就完成了集群环境初始化。

3.2.3 k8sdeploy项目介绍

k8sdeploy项目下有七个子目录:addons、app、binary、haproxy、initialize、keepalived、kubeadm,顾名思义,每个目录都有其相关功能:

  • addons:Kubernetes集群的相关插件,在集群安装完成后,为了更好的管理集群。
    • calico:网络插件, 集群安装完成后,需要执行此目录中的文件;
    • coredns:DNS服务,使用二进制包安装完成集群后,需要执行此目录中的文件;
    • dashboard:集群部署完成后,执行此目录中的文件安装UI控制台;
    • ingress-nginx:将集群内的服务发布到集群外。
  • app:介绍部署应用程序时,使用到的程序。
  • binary:二进制包安装Kubernetes集群所需的Ansible Playbook脚本及依赖的文件,相关目录有:
    • pki:生成证书需要的文件;
    • deployEtcd:安装ETCD集群的脚本及相关文件,二进制环境需要自己部署ETCD;
    • deployApiServer:安装Kube-apiserver组件的脚本及相关文件;
    • deployControllerManager:安装Kube-controller-manager组件的脚本及相关文件;
    • deployScheduler:安装Kube-scheduler组件的脚本及相关文件;
    • deployKubelet:安装Kubelet组件的脚本及相关文件;
    • deployKubeProxy:安装Kubeproxy组件的脚本及相关文件;
  • initialize:用来执行Kubernetes集群环境的初始化,包含两个Ansible Playbook文件(installPackages.yaml和initEnv.yaml)和一个config目录。
    • installPackages.yaml:用来安装依赖包,实现了集群环境初始化的第2和6步,需要先执行此文件;
    • initEnv.yaml:实现了集群环境初始化中的第3、4、5、7步;
    • config:目录里是Ansible Playbook依赖的配置文件,有docker的daemon.json文件和系统参数文件;
    • 使用方法:
    代码语言:javascript
    复制
    cd k8sdeploy/initialize
    # 安装的依赖包比较多,这个过程会比较慢
    ansible-playbook installPackages.yaml
    ansible-playbook initEnv.yaml
  • kubeadm:Kubeadm工具安装高可用Kubernetes集群所需的文件:
    • installKubeadm.yaml:用来安装kubeadm、kubelet和kubectl
    • config:Kubernetes相关的yum源文件
    • kubernetes:kubeadm安装Kubernetes集群的配置文件
    • 使用方法:
    代码语言:javascript
    复制
    cd k8sdeploy/kubeadm
    ansible-playbook installKubeadm.yam
  • haproxy:HaProxy的配置文件,可直接拷贝:
    • 使用方法:
    代码语言:javascript
    复制
    cp k8sdeploy/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg
  • keepalived:包含两个keepalived配置文件,一主一备需按角色拷贝,还包含一个检测脚本,检测到HaProxy异常时实现Keepalived的主从切换:
    • 使用方法:
    代码语言:javascript
    复制
    # keepalived master node
    cp k8sdeploy/keepalived/master-keepalived.conf /etc/keepalived/keepalived.conf
    cp k8sdeploy/keepalived/checkHaproxy.sh /etc/keepalived/checkHaproxy.sh
    # keepalived backup node
    cp k8sdeploy/keepalived/backup-keepalived.conf /etc/keepalived/keepalived.conf
    cp k8sdeploy/keepalived/checkHaproxy.sh /etc/keepalived/checkHaproxy.sh

3.4 高可用环境配置

Kubernetes作为重要的容器治理平台,保障其自身高可靠稳定运行尤为重要,这需要我们从三方面考虑:

  • ETCD:ETCD存储Kubernetes集群的状态信息,我们需要把ETCD部署为高可用集群。
  • 管理层服务:kube-scheduler和kube-controller-manager都属于管理层服务,使用一主多从的高可用方案,在同一时刻只允许一个服务处理具体的任务。Kubernetes中实现了一套简单的选主逻辑,依赖Etcd实现scheduler和controller-manager的选主功能。
  • Kube-apiserver:Kubernetes的接入层服务主要是kube-apiserver。kube-apiserver本身是无状态的,它的主要任务是把资源数据存储到Etcd中,后续具体的业务逻辑由kube-scheduler和kube-controller-manager执行。 可以同时启动多个kebu-apiserver服务,通过HaProxy进行流量负载,使用Keepalived负责HaProxy的高可用。
3.4.1 部署HaProxy

HaProxy是一个使用C语言编写的自由及开放源代码软件,提供高可用性、负载均衡,以及基于TCP和HTTP的应用程序代理,并能对后端服务进行健康监测,把流量转发给健康的后端。

在准备好的两台主机(lb01、lb02)上执行以下操作:

  1. 安装HaProxy:
代码语言:javascript
复制
yum install -y haproxy
  1. 修改haproxy.cfg配置文件:
代码语言:javascript
复制
git clone https://github.com/weiwendi/k8sdeploy.git
cp k8sdeploy/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg

在haproxy.cfg文件中,有几处配置需要根据实际环境修改:

  • frontend中监听的端口,此端口是通过VIP访问Kube-apiserver的端口
  • backend中对应server的IP,此IP是Kubernetes Master主机的IP,端口为Kube-apiserver的端口

  1. 修改日志输出:

默认HaProxy的日志输出在/var/log/messages文件中,为了便于查看及管理,我们把它输出到/var/log/haproxy/haproxy.log文件中:

代码语言:javascript
复制
# 修改/etc/sysconfig/rsyslog文件为如下内容
cat /etc/sysconfig/rsyslog
SYSLOGD_OPTIONS="-r"

# 修改/etc/rsyslog.conf文件
vim /etc/rsyslog.conf
# 取消以下选项的注释:
$ModLoad imudp
$UDPServerRun 514
#增加以下内容:
# haproxy -r 2
local2.*                               /var/log/haproxy/haproxy.log
  1. 重启服务:
代码语言:javascript
复制
systemctl restart rsyslog
systemctl start haproxy
3.4.2 部署Keepalived

Keepalived是一个使用C语言编写的自由及开放源代码软件。主要为Linux系统和基于Linux的基础设施提供简单而健壮的高可用性工具,通过VRRP协议实现。

在准备好的两台主机上(lb01、lb02)执行以下操作:

  1. 安装Keepalived:
代码语言:javascript
复制
yum install -y keepalived
  1. 修改/etc/keepalived/keepalived.conf配置文件: 配置文件分为主配置文件和备配置文件,需根据主机角色分发:
代码语言:javascript
复制
[root@lb01 ~]# cp k8sdeploy/keepalived/master-keepalived.conf /etc/keepalived/keepalived.conf
[root@lb02 ~]# cp k8sdeploy/keepalived/backup-keepalived.conf /etc/keepalived/keepalived.conf

配置文件中有一些选项需要根据实际环境修改:

  • notification_email定义的邮箱地址,填写主从切换后接受报警的邮箱
  • notification_email_from 发送主从切换警报的邮箱
  • smtp_server 发件邮箱使用的smtp服务器
  • interface eth0 绑定VIP地址的网卡名称
  • virtual_ipaddress 填写你实际使用的VIP地址

  1. 拷贝健康检查文件到主备节点,并确保对该文件有执行权限:
代码语言:javascript
复制
cp k8sdeploy/keepalived/checkHaproxy.sh /etc/keepalived/checkHaproxy.sh
chmod +x /etc/keepalived/checkHaproxy.sh
  1. 修改输出日志文件: 默认Keepalived的日志会打印在/var/log/messages文件中,为了方便查看和管理,我们把它的日志内容输出到/var/log/keepalived/keepalived.log中。
代码语言:javascript
复制
# /etc/sysconfig/keepalived文件内容修改如下:
cat /etc/sysconfig/keepalived
KEEPALIVED_OPTIONS="-D -d -S 0"

# 在/etc/rsyslog.conf文件中增加如下内容:
vim /etc/rsyslog.conf
# keepalived -S 0
local0.*                                     /var/log/keepalived/keepalived.log
  1. 重启服务:
代码语言:javascript
复制
# 重启rsyslog服务
systemctl restart rsyslog

# 启动keepalived(先启动主,再启动从)
systemctl start keepalived
  1. 在主节点上查看VIP的是否绑定成功:
代码语言:javascript
复制
[root@lb01 ~]# ip addr

到这里,准备环境已经完成,接下来,进入Kubernetes高可用集群的安装。

可以手动停止主节点的HaProxy服务,验证VIP是否自动漂移到从节点。

3.5 通过Kubeadm安装高可用Kubernetes集群

Kubeadm方式安装Kubernetes集群的过程相对简单,除kubelet外,其他组件均以容器的方式运行,并且支持高可用部署,我们无需考虑ETCD及控制层面的高可用,只需保证在HaProxy中配置了Kube-apiserver的流量负载。

3.5.1 安装kubeadm、kubelet及kubectl

进入k8sdeploy项目的kubeadm目录,执行installKubeadm.yaml安装kubeadm、kubelet和kubectl:

代码语言:javascript
复制
[root@km01 ~]# cd k8sdeploy/kubeadm
[root@km01 kubeadm]# ansible-playbook installKubeadm.yaml
3.5.2 使用kubeadm安装Kubernetes高可用集群

安装完kubeadm工具后,就可以使用该工具安装Kubernetes集群了,我已经创建好了安装Kubernetes集群时依赖的配置文件,但有几个配置项需要根据实际环境修改:

  • dnsDomain: 服务可用域,默认是cluster.local,该配置文件中定义的是aiops.red
  • podSubnet:Pod网络
  • serviceSubnet: Service网络
  • imageRepository: 集群使用的镜像仓库,默认是k8s.gcr.io,可以使用我的阿里云镜像仓库,已经准备好了所需的镜像,地址是registry.cn-hangzhou.aliyuncs.com/weiwendi
代码语言:javascript
复制
[root@km01 ~]# cd k8sdeploy/kubeadm/kubernetes/
[root@km01 kubernetes]# kubeadm init --config=kubeadm-config.yaml --upload-certs

命令执行完成,终端上会打印很多内容,把类似下面的这段输出拷贝出来:

代码语言:javascript
复制
Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:
 mkdir -p $HOME/.kube
 sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
 sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
 https://kubernetes.io/docs/concepts/cluster-administration/addons/

You can now join any number of the control-plane node running the following command on each as root:
 kubeadm join 192.168.0.111:16443 --token 2yzik9.g5tlnr5cr0ocdcr0 \
  --discovery-token-ca-cert-hash sha256:3327709183ac204ca1e3e986d9c311a6222d904070c72ee1260a707d9c5d1810 \
  --control-plane --certificate-key c672459d595fce1b563e3150e342b692fb4df3a61b51ecd634f05fea5c1a9110

Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.

Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.0.111:16443 --token 2yzik9.g5tlnr5cr0ocdcr0 \
  --discovery-token-ca-cert-hash sha256:3327709183ac204ca1e3e986d9c311a6222d904070c72ee1260a707d9c5d1810
...
3.5.3 配置kubectl

按照输出内容,配置Kubernetes集群的命令行管理工具kubectl:

代码语言:javascript
复制
[root@km01 ~]# mkdir -p $HOME/.kube
[root@km01 ~]# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
3.5.4 配置集群网络

实现Kubernetes集群网络的方案很多,Calico工具就实现了一个很优秀的Kubernetes集群网络解决方案:

代码语言:javascript
复制
[root@km01 ~]# cd k8sdeploy/addons/calico/
[root@km01 calico]# kubectl apply -f calico.yaml

calico.yaml文件中也有两处配置需要注意:

  • CALICO_IPV4POOL_CIDR:该字段的value定义Pod网段,要和kubeadm-config.yaml中的podSubnet字段值一致。
  • image:要确保文件中的镜像仓库是可以访问的
3.5.5 为Kubernetes集群添加Master

输出内容中提示了如何将新的Master加入集群,粘贴并在目标主机执行:

代码语言:javascript
复制
# Master2
[root@km02 ~]# kubeadm join 192.168.0.111:16443 --token 2yzik9.g5tlnr5cr0ocdcr0 \
  --discovery-token-ca-cert-hash sha256:3327709183ac204ca1e3e986d9c311a6222d904070c72ee1260a707d9c5d1810 \
  --control-plane --certificate-key c672459d595fce1b563e3150e342b692fb4df3a61b51ecd634f05fea5c1a9110

# Master3
[root@km02 ~]# kubeadm join 192.168.0.111:16443 --token 2yzik9.g5tlnr5cr0ocdcr0 \
  --discovery-token-ca-cert-hash sha256:3327709183ac204ca1e3e986d9c311a6222d904070c72ee1260a707d9c5d1810 \
  --control-plane --certificate-key c672459d595fce1b563e3150e342b692fb4df3a61b51ecd634f05fea5c1a9110
3.5.6 为Kubernetes集群添加Node

输出内容中同样提示了如何将Node加入集群,粘贴并在目标主机执行:

代码语言:javascript
复制
# Node1
[root@kn01 ~]# kubeadm join 192.168.0.111:16443 --token 2yzik9.g5tlnr5cr0ocdcr0 \
  --discovery-token-ca-cert-hash sha256:3327709183ac204ca1e3e986d9c311a6222d904070c72ee1260a707d9c5d1810

# Node2
[root@kn02 ~]# kubeadm join 192.168.0.111:16443 --token 2yzik9.g5tlnr5cr0ocdcr0 \
  --discovery-token-ca-cert-hash sha256:3327709183ac204ca1e3e986d9c311a6222d904070c72ee1260a707d9c5d1810
3.5.7 查看集群各组件的可用性

集群安装完成了,可以使用命令查看组件的运行状态:

代码语言:javascript
复制
# 查看集群状态
[root@km01 ~]# kubectl get cs
NAME         STATUS  MESSAGE       ERROR
scheduler      Healthy  ok          
controller-manager  Healthy  ok          
etcd-0        Healthy  {"health":"true"}
[root@km01 ~]# curl -k https://192.168.0.111:16443/healthz
ok
# 查看集群中的主机
[root@km01 ~]# kubectl get nodes
3.5.8 部署Dashboard

Dashboard 是基于网页的 Kubernetes 用户界面。可以使用 Dashboard 将容器应用部署到 Kubernetes 集群中,也可以对容器应用排错,还能管理集群资源。可以使用 Dashboard 获取运行在集群中的应用的概览信息,也可以创建或者修改 Kubernetes 资源(如 Deployment,Job,DaemonSet 等等)。例如,可以对 Deployment 实现弹性伸缩、发起滚动升级、重启 Pod 或者使用向导创建新的应用。

我在k8sdeploy/addons/dashboard/目录下已经准备好了部署Dashboard的yaml文件,端口类型为NodePort,监听TCP30000端口,如果你集群中各主机的30000端口已被占用,请修改此文件的NodePort值及HaProxy配置文件中的对应端口号:

代码语言:javascript
复制
[root@km01 ~]# cd k8sdeploy/addons/dashboard/
[root@km01 dashboard]# kubectl apply -f dashboard.yaml
# 查看dashboard的运行情况
[root@km01 dashboard]# kubectl get pods -n kubernetes-dashboard
[root@km01 dashboard]# kubectl get services -n kubernetes-dashboard

Dashboard部署完成后,在浏览器中输入https://vip:17443访问,因为用的是IP地址,而Dashboard又不支持HTTP,所以会提示证书问题,点击“高级”按钮,点击“继续访问”。登录时的验证方式有Kubeconfig和token两种,建议采用token方式。查看token:

代码语言:javascript
复制
[root@km01 ~]# kubectl get secret -n kubernetes-dashboard
[root@km01 ~]# kubectl describe secret kubernetes-dashboard-token-ddxbs -n kubernetes-dashboard

这就是使用Kubeadm部署高可用Kubernetes集群的相关步骤,整个过程还是很简单的。接下来介绍使用二进制包部署高可用Kubernetes集群。

拷贝token字段的值,粘贴进浏览器的验证框,点击“登录”按钮。

3.6 通过二进制包安装高可用Kubernetes集群

采用二进制包安装相比Kubeadm会复杂一些,但维护相对简单。

3.6.1 创建集群所需证书及密钥
  1. 安装cfssl命令,用以生成证书及密钥:
代码语言:javascript
复制
[root@km01 ~]# wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -O /usr/local/bin/cfssl
[root@km01 ~]# wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -O /usr/local/bin/cfssljson
[root@km01 ~]# chmod +x /usr/local/bin/cfssl*
[root@km01 ~]# cfssl version
  1. 生成根证书和私钥 根证书是集群所有节点共享的,只需要创建一个CA证书,签名后续创建的所有证书:
代码语言:javascript
复制
[root@km01 ~]# cd k8sdeploy/binary/pki
[root@km01 pki]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca

# 生成的ca-key.pem和ca.pem便是我们需要的密钥和证书
[root@km01 pki]# ls
ca-config.json  ca.csr  ca-csr.json  ca-key.pem  ca.pem

# 将ca-key.pem和ca.pem拷贝到每个主节点的/etc/kubernetes/pki/目录
# 创建/etc/kubernetes/pki/目录
[root@km01 pki]# ansible k8sm -m file -a 'dest=/etc/kubernetes/pki/ state=directory'

# 拷贝文件
[root@km01 pki]# scp *.pem 192.168.0.16:/etc/kubernetes/pki/
[root@km01 pki]# scp *.pem 192.168.0.17:/etc/kubernetes/pki/
[root@km01 pki]# scp *.pem 192.168.0.18:/etc/kubernetes/pki/
3.6.2 二进制包下载

Kubernetes1.17.0相关的二进制包我上传在了百度网盘,链接:https://pan.baidu.com/s/1sMyqWZCwzAEHuCZAmREKJg,提取码:6jr2,保存到/tmp目录下:

代码语言:javascript
复制
[root@km01 ~]# wget -P /tmp/ https://dl.k8s.io/v1.17.0/kubernetes-server-linux-amd64.tar.gz
[root@km01 ~]# tar zxf /tmp/kubernetes-server-linux-amd64.tar.gz -C /tmp/

需要将这些包解压到Ansible节点的/tmp目录,方便包分发。

ETCD3.3.18的官方GitHub下载地址:

代码语言:javascript
复制
[root@km01 ~]# wget -P /tmp/ https://github.com/etcd-io/etcd/releases/download/v3.3.18/etcd-v3.3.18-linux-amd64.tar.gz
[root@km01 ~]# tar zxf /tmp/etcd-v3.3.18-linux-amd64.tar.gz -C /tmp/
3.6.3 部署ETCD集群

在k8sdeploy/binary/deployEtcd/目录中,已经准备好了自动部署ETCD集群的Ansible脚本。

  1. 生成ETCD证书及私钥:
代码语言:javascript
复制
[root@km01 ~]# cd k8sdeploy/binary/pki/etcd
[root@km01 etcd]# cfssl gencert -ca=../ca.pem -ca-key=../ca-key.pem -config=../ca-config.json -profile=kubernetes etcd-csr.json | cfssljson -bare etcd
[root@km01 etcd]# ls etcd*.pem

这些证书及私钥需要拷贝到ETCD节点的/etc/kubernetes/pki/目录中,已在Ansible脚本里实现,无需手动拷贝。

  1. 进入k8sdeploy/binary/deployEtcd目录,执行deployEtcd.yaml,完成ETCD集群的部署:
代码语言:javascript
复制
[root@km01 deployEtcd]# ansible-playbook deployEtcd.yaml
# 查看ETCD节点信息
[root@km01 deployEtcd]# etcdctl --ca-file=/etc/kubernetes/pki/ca.pem --cert-file=/etc/kubernetes/pki/etcd.pem --key-file=/etc/kubernetes/pki/etcd-key.pem member list
3.6.4 部署Kube-apiserver服务
  1. 生成kube-apiserver所需的证书和私钥: 下面的命令生成kubernetes.pem和kubernetes-key.pem,需要把这两个文件拷贝到所有Master主机的/etc/kubernetes/pki目录里:
代码语言:javascript
复制
[root@km01 ~]# cd k8sdeploy/binary/pki/api-server
[root@km01 api-server]# cfssl gencert -ca=../ca.pem \
    -ca-key=../ca-key.pem \    
    -config=../ca-config.json -profile=kubernetes \    
    kubernetes-csr.json | cfssljson -bare kubernetes
  1. 进入k8sdeploy/binary/deployApiServer目录执行部署脚本:
代码语言:javascript
复制
[root@km01 ~]# cd k8sdeploy/binary/deployApiServer
[root@km01 deployApiServer]# ansible-playbook deployApiServer.yaml
3.6.5 检查高可用环境的运行状态

3.4节配置了高可用集群,在浏览器中访问http://192.168.0.111/admin?stats页面,,查看Kube-apiserver的运行状态,需要把192.168.0.111替换为你的VIP地址。也可以手动停止主HaProxy,验证VIP是否漂移,在此过程中,执行以下命令,看结果是否不同:

代码语言:javascript
复制
curl -k https://192.168.0.17:6443
3.6.6 安装Kubectl

kubectl可以安装在连通Kubernetes集群的任一主机上,本环境在192.168.0.16Master主机上。

  1. 拷贝kubectl命令,并创建配置文件所需的目录:
代码语言:javascript
复制
[root@km01 ~]# cp -a /tmp/kubernetes/server/bin/kubectl /usr/local/bin/
[root@km01 ~]# mkdir ~/.kube
  1. 创建证书和私钥:
代码语言:javascript
复制
[root@km01 ~]# cd k8sdeploy/binary/pki/kubectl
[root@km01 kubectl]# cfssl gencert -ca=../ca.pem \
    -ca-key=../ca-key.pem -config=../ca-config.json \
    -profile=kubernetes \
    admin-csr.json | cfssljson -bare admin
  1. 创建kubeconfig配置文件: kubeconfig 为 kubectl 的配置文件,包含访问 kube-apiserver 所需的信息,如 kube-apiserver 地址、CA 证书和自身使用的证书:
代码语言:javascript
复制
# 设置集群参数,--server的地址是VIP的地址及端口
[root@km01 kubectl]# kubectl config set-cluster kubernetes \
  --certificate-authority=../ca.pem \
  --embed-certs=true \
  --server=https://192.168.0.111:16443 \
  --kubeconfig=kube.config

# 设置客户端认证参数
[root@km01 kubectl]# kubectl config set-credentials admin \
  --client-certificate=admin.pem \
  --client-key=admin-key.pem \
  --embed-certs=true \
  --kubeconfig=kube.config

# 设置上下文参数
[root@km01 kubectl]# kubectl config set-context kubernetes \
  --cluster=kubernetes \
  --user=admin \
  --kubeconfig=kube.config

# 设置默认上下文
[root@km01 kubectl]# kubectl config use-context kubernetes --kubeconfig=kube.config


# 将kube.config文件拷贝到~/.kube/目录
[root@km01 kubectl]# cp kube.config ~/.kube/config
  1. 赋权,授予 kubernetes 证书访问 kubelet API 的权限: 在执行kubectl exec、run、logs等命令时,kube-apiserver会将请求转发到kubelet。这里定义 RBAC 规则,授权kube-apiserver 调用kubelet API:
代码语言:javascript
复制
[root@km01 kubectl]# kubectl create clusterrolebinding kube-apiserver:kubelet-apis \
    --clusterrole=system:kubelet-api-admin --user kubernetes
  1. 验证:
代码语言:javascript
复制
# 查看集群信息
[root@km01 kubectl]# kubectl cluster-info
[root@km01 kubectl]# kubectl get all --all-namespaces
[root@km01 kubectl]# kubectl get componentstatuses
3.6.7 部署Kube-controller-manager服务
  1. 生成kube-controller-manager所需的证书及私钥:
代码语言:javascript
复制
[root@km01 ~]# cd k8sdeploy/binary/pki/kube-controller-manager
[root@km01 kube-controller-manager]# cfssl gencert -ca=../ca.pem \
    -ca-key=../ca-key.pem   -config=../ca-config.json \
    -profile=kubernetes kube-controller-manager-csr.json | cfssljson \
    -bare controller-manager
[root@km01 kube-controller-manager]# ls controller-manager*
controller-manager.csr  controller-manager-key.pem  controller-manager.pem

生成的三个文件需要拷贝到每个Master主机,该步骤已包含在Ansible Playbook文件中。

  1. 创建kube-controller-manager的配置文件kubeconfig
代码语言:javascript
复制
# 创建kubeconfig
[root@km01 kube-controller-manager]# kubectl config set-cluster kubernetes \
    --certificate-authority=../ca.pem --embed-certs=true \
    --server=https://192.168.0.111:16443 \
    --kubeconfig=kube-controller-manager.kubeconfig
root@km01 kube-controller-manager]# kubectl config set-credentials \
    system:kube-controller-manager --client-certificate=controller-manager.pem \
    --client-key=controller-manager-key.pem --embed-certs=true \
    --kubeconfig=kube-controller-manager.kubeconfig
[root@km01 kube-controller-manager]# kubectl config set-context \
    system:kube-controller-manager --cluster=kubernetes \
    --user=system:kube-controller-manager \
    --kubeconfig=kube-controller-manager.kubeconfig
[root@km01 kube-controller-manager]# kubectl config use-context \
    system:kube-controller-manager \
    --kubeconfig=kube-controller-manager.kubeconfig

将kube-controller-manager.kubeconfig分发到所有Master主机,该步骤已包含在Ansible Playbook文件中。

  1. 进入k8sdeploy/binary/deployControllerManager执行部署脚本:
代码语言:javascript
复制
[root@km01 deployControllerManager]# ansible-playbook deployControllerManager.yaml
3.6.8 部署Kube-scheduler服务
  1. 创建证书和私钥:
代码语言:javascript
复制
[root@km01 ~]# cd k8sdeploy/binary/pki/kube-scheduler
[root@km01 kube-scheduler]# 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. 创建scheduler的kubeconfig文件:
代码语言:javascript
复制
[root@km01 kube-scheduler]# kubectl config set-cluster kubernetes \
--certificate-authority=../ca.pem --embed-certs=true \
--server=https://192.168.0.111:16443 \
--kubeconfig=kube-scheduler.kubeconfig
[root@km01 kube-scheduler]# 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
[root@km01 kube-scheduler]# kubectl config set-context \
    system:kube-scheduler --cluster=kubernetes \
--user=system:kube-scheduler \
--kubeconfig=kube-scheduler.kubeconfig
[root@km01 kube-scheduler]# kubectl config use-context system:kube-scheduler --kubeconfig=kube-scheduler.kubeconfig

将kube-scheduler.kubeconfig分发到所有Master主机,该步骤已包含在Ansible Playbook文件中。

  1. 进入k8sdeploy/binary/deployScheduler执行部署脚本:
代码语言:javascript
复制
[root@km01 deployScheduler]# ansible-playbook deployScheduler.yaml
3.6.9 部署Kubelet服务
  1. 创建bootstrap配置文件
代码语言:javascript
复制
# 创建token
[root@km01 ~]# cd k8sdeploy/binary/pki/kubectl
[root@km01 kubectl]# export BOOTSTRAP_TOKEN=$(/tmp/kubernetes/server/bin/kubeadm token create \
      --description kubelet-bootstrap-token \
      --groups system:bootstrappers:worker \
      --kubeconfig kube.config)
# 设置集群参数
[root@km01 kubectl]# kubectl config set-cluster kubernetes \
      --certificate-authority=../ca.pem \
      --embed-certs=true \
      --server=https://192.168.0.111:6443 \
      --kubeconfig=kubelet-bootstrap.kubeconfig
# 设置客户端认证参数
[root@km01 kubectl]# kubectl config set-credentials kubelet-bootstrap \
      --token=${BOOTSTRAP_TOKEN} \
      --kubeconfig=kubelet-bootstrap.kubeconfig
# 设置上下文参数
[root@km01 kubectl]# kubectl config set-context default \
      --cluster=kubernetes \
      --user=kubelet-bootstrap \
      --kubeconfig=kubelet-bootstrap.kubeconfig
# 设置默认上下文
[root@km01 kubectl]# kubectl config use-context default --kubeconfig=kubelet-bootstrap.kubeconfig

把生成的kubelet-bootstrap.kubeconfig文件拷贝到每个Node上,因为我们Master也安装了Kubelet,也需要拷贝到Master上。另外还需要把ca.pem证书拷贝到Node节点的/etc/kubernetes/pki目录中。

  1. 为bootstrap赋权
代码语言:javascript
复制
[root@km01 kubectl]# kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --group=system:bootstrappers
  1. 进入k8sdeploy/binary/deployKubelet目录执行部署脚本:
代码语言:javascript
复制
[root@km01 deployKubelet]# ansible-playbook deployKubelet.yaml
  1. Approve bootstrap请求:
代码语言:javascript
复制
[root@km01 ~]# kubectl get csr
[root@km01 ~]# kubectl certificate approve <name>
3.6.10 部署Kube-proxy服务
  1. 创建证书和私钥:
代码语言:javascript
复制
[root@km01 ~]# cd k8sdeploy/binary/pki/kube-proxy
[root@km01 kube-proxy]# 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. 创建kube-proxy的kubeconfig文件
代码语言:javascript
复制
# 创建kube-proxy.kubeconfig
[root@km01 kube-proxy]# kubectl config set-cluster kubernetes \
    --certificate-authority=../ca.pem --embed-certs=true \
    --server=https://192.168.0.111:16443 --kubeconfig=kube-proxy.kubeconfig
[root@km01 kube-proxy]# kubectl config set-credentials kube-proxy \
    --client-certificate=kube-proxy.pem --client-key=kube-proxy-key.pem \
    --embed-certs=true --kubeconfig=kube-proxy.kubeconfig
[root@km01 kube-proxy]# kubectl config set-context default --cluster=kubernetes \
    --user=kube-proxy --kubeconfig=kube-proxy.kubeconfig
[root@km01 kube-proxy]# kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
  1. 进入k8sdeploy/binary/deployKubeProxy目录执行部署脚本:
代码语言:javascript
复制
[root@km01 deployKubeProxy]# ansible-playbook deployKubeProxy.yaml
3.6.11 安装CNI插件——Calico
代码语言:javascript
复制
[root@km01 ~]# cd k8sdeploy/addons/calico/
[root@km01 calico]# kubectl apply -f calico.yaml
3.6.12 安装CoreDNS

CoreDNS 是一个灵活可扩展的 DNS 服务器,可以作为 Kubernetes 集群 的DNS。与 Kubernetes 一样,CoreDNS 项目由 CNCF 持有。

代码语言:javascript
复制
[root@km01 ~]# cd k8sdeploy/addons/coredns/
[root@km01 calico]# kubectl apply -f coredns.yaml
3.6.13 安装DashBoard
代码语言:javascript
复制
[root@km01 ~]# cd k8sdeploy/addons/dashboard/
[root@km01 dashboard]# kubectl apply -f dashboard.yaml
3.6.14 集群可用性测试

我们已经正常运行了Calico、CoreDNS和DashBoard,但谨慎起见,可通过以下几项,验证集群可用性:

部署Nginx Deployment:

代码语言:javascript
复制
[root@km01 ~]# cd k8sdeploy/app/nginx
[root@km01 nginx]# kubectl apply -f nginx.yaml
  1. IP测试
代码语言:javascript
复制
# 测试pod ip的连通性
# 获取nginx pod的IP地址,在集群中任意节点上ping该IP
[root@km01 nginx]# kubectl get pod -o wide

# 测试service ip及nodePort的连通性
# 获取nginx service的IP和nodePort,在集群中任意节点上curl该地址
[root@km01 nginx]# kubectl get service
[root@km01 nginx]# curl http://serviceip
[root@km01 nginx]# curl http://nodeIP:nodePort
  1. 域名测试

使用kubectl exec命令登录nginx pod容器:

代码语言:javascript
复制
[root@km01 nginx]# kubectl exec -it nginx-85545d47d4-x8smd sh
# ping kubernetes
# ping nginx
# ping kube-dns.kube-system
# Kubernetes Service禁ping了,但能正确解析到域名的IP地址

Service的名称格式:service-name.namespace.svc.cluster.local。

Binary的安装也介绍完了,相比Kubeadm方式是不是复杂了很多,不过也没关系,我们已经搞定了。

接下来,介绍在Kubernetes集群中部署程序,以及生产中的常用操作。

文章转载自魏文弟。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-02-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CNCF 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一 主要技术点
  • 二 Kubernetes集群介绍
  • 三 部署高可用Kubernetes集群
    • 3.1 安装环境介绍
      • 3.2 集群安装前的准备
        • 3.2.1 安装配置Ansible
        • 3.2.2 集群环境初始化(Kubernetes集群中的主机都要执行)
        • 3.2.3 k8sdeploy项目介绍
      • 3.4 高可用环境配置
        • 3.4.1 部署HaProxy
        • 3.4.2 部署Keepalived
      • 3.5 通过Kubeadm安装高可用Kubernetes集群
        • 3.5.1 安装kubeadm、kubelet及kubectl
        • 3.5.2 使用kubeadm安装Kubernetes高可用集群
        • 3.5.3 配置kubectl
        • 3.5.4 配置集群网络
        • 3.5.5 为Kubernetes集群添加Master
        • 3.5.6 为Kubernetes集群添加Node
        • 3.5.7 查看集群各组件的可用性
        • 3.5.8 部署Dashboard
      • 3.6 通过二进制包安装高可用Kubernetes集群
        • 3.6.1 创建集群所需证书及密钥
        • 3.6.2 二进制包下载
        • 3.6.3 部署ETCD集群
        • 3.6.4 部署Kube-apiserver服务
        • 3.6.5 检查高可用环境的运行状态
        • 3.6.6 安装Kubectl
        • 3.6.7 部署Kube-controller-manager服务
        • 3.6.8 部署Kube-scheduler服务
        • 3.6.9 部署Kubelet服务
        • 3.6.10 部署Kube-proxy服务
        • 3.6.11 安装CNI插件——Calico
        • 3.6.12 安装CoreDNS
        • 3.6.13 安装DashBoard
        • 3.6.14 集群可用性测试
    相关产品与服务
    容器服务
    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档