kubernetes
第1章:Kubernetes入门
1.kubernetes简介
Kubernetes 是一个可移植的、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。Kubernetes 拥有一个庞大且快速增长的生态系统。
Kubernetes 的服务、支持和工具广泛可用。 一、简介 Kubernetes 是一个全新的基于容器技术的分布式领先方案。简称:K8S。它是 Google 开源的容器集群管理系统,它的设计灵感来自于 Google 内部的一个叫作 Borg 的容器管理系统。继承了 Google 十余年的容器集群使用经验。它为容器化的应用提供了部署运行、资源调度、服务发现和动态伸缩等一些列完整的功能,极大地提高了大规模容器集群管理的便捷性。
kubernetes 是一个完备的分布式系统支撑平台。具有完备的集群管理能力,多扩多层次的安全防护和准入机制、多租户应用支撑能力、透明的服务注册和发现机制、內建智能负载均衡器、强大的故障发现和自我修复能力、服务滚动升级和在线扩容能力、可扩展的资源自动调度机制以及多粒度的资源配额管理能力。
在集群管理方面,Kubernetes 将集群中的机器划分为一个 Master 节点和一群工作节点 Node,其中,在 Master 节点运行着集群管理相关的一组进程 kube-apiserver、kube-controller-manager 和 kube-scheduler,这些进程实现了整个集群的资源管理、Pod 调度、弹性伸缩、安全控制、系统监控和纠错等管理能力,并且都是全自动完成的。
Node 作为集群中的工作节点,运行真正的应用程序,在 Node 上 Kubernetes 管理的最小运行单元是 Pod。Node 上运行着 Kubernetes 的 kubelet、kube-proxy 服务进程,这些服务进程负责 Pod 的创建、启动、监控、重启、销毁以及实现软件模式的负载均衡器。
在 Kubernetes 集群中,它解决了传统 IT 系统中服务扩容和升级的两大难题。如果今天的软件并不是特别复杂并且需要承载的峰值流量不是特别多,那么后端项目的部署其实也只需要在虚拟机上安装一些简单的依赖,将需要部署的项目编译后运行就可以了。但是随着软件变得越来越复杂,一个完整的后端服务不再是单体服务,而是由多个职责和功能不同的服务组成,服务之间复杂的拓扑关系以及单机已经无法满足的性能需求使得软件的部署和运维工作变得非常复杂,这也就使得部署和运维大型集群变成了非常迫切的需求。
kubernetes 的出现不仅主宰了容器编排的市场,更改变了过去的运维方式,不仅将开发与运维之间边界变得更加模糊,而且让 DevOps 这一角色变得更加清晰,每一个软件工程师都可以通过 Kubernetes 来定义服务之间的拓扑关系、线上的节点个数、资源使用量并且能够快速实现水平扩容、蓝绿部署等在过去复杂的运维操作。
1.架构
Kubernetes 遵循非常传统的客户端服务端架构,客户端通过 RESTful 接口或者直接使用 kubectl 与 Kubernetes 集群进行通信,这两者在实际上并没有太多的区别,后者也只是对 Kubernetes 提供的 RESTful API 进行封装并提供出来。每一个 Kubernetes 集群都由一组 Master 节点和一系列的 Worker 节点组成,其中 Master 节点主要负责存储集群的状态并为 Kubernetes 对象分配和调度资源。
1.1.Master
它主要负责接收客户端的请求,安排容器的执行并且运行控制循环,将集群的状态向目标状态进行迁移,
Master 节点内部由三个组件构成:
1.1.1.API Server
负责处理来自用户的请求,其主要作用就是对外提供 RESTful 的接口,包括用于查看集群状态的读请求以及改变集群状态的写请求,也是唯一一个与 etcd 集群通信的组件。
1.1.2.Controller
管理器运行了一系列的控制器进程,这些进程会按照用户的期望状态在后台不断地调节整个集群中的对象,当服务的状态发生了改变,控制器就会发现这个改变并且开始向目标状态迁移。
1.1.3.Scheduler
调度器其实为 Kubernetes 中运行的 Pod 选择部署的 Worker 节点,它会根据用户的需要选择最能满足请求的节点来运行 Pod,它会在每次需要调度 Pod 时执行。
1.2.Node
Node 节点实现相对简单一点,主要是由 kubelet 和 kube-proxy 两部分组成: kubelet 是一个节点上的主要服务,它周期性地从 API Server 接受新的或者修改的 Pod 规范并且保证节点上的 Pod 和其中容器的正常运行,还会保证节点会向目标状态迁移,该节点仍然会向 Master 节点发送宿主机的健康状况。 kube-proxy 负责宿主机的子网管理,同时也能将服务暴露给外部,其原理就是在多个隔离的网络中把请求转发给正确的 Pod 或者容器。
1.3.kubernetes结构图

在这张系统架构图中,我们把服务分为运行在工作节点上的服务和组成集群级别控制板的服务。
主要由以下几个核心组件组成:
1. etcd保存了整个集群的状态
2. apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制
3. controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等
4. scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上
5. kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理
6. Container runtime负责镜像管理以及Pod和容器的真正运行(CRI)
7. kube-proxy负责为Service提供cluster内部的服务发现和负载均衡除了核心组件,还有一些推荐的组件:
1.kube-dns负责为整个集群提供DNS服务
2.Ingress Controller为服务提供外网入口
3.Heapster提供资源监控
4.Dashboard提供GUIFederation提供跨可用区的集群
5.Fluentd-elasticsearch提供集群日志采集、存储与查询
第2章: kubernetes 部署
一、 kubeadm部署篇
Kubernetes 有两种方式,第一种是二进制的方式,可定制但是部署复杂容易出错;第二种是 kubeadm 工具安装,部署简单,不可定制化。本次我们部署 kubeadm 版
1.部署系统版本
| 软件 |
版本 |
| CentOS |
Centos 7.7 |
| Docker |
V19.03.12 |
| K8s |
V1.19.1 |
| Flannel |
V0.13.0 |
| Kernel-lm |
kernel-lt-4.4.245-1.el7.elrepo.x86_64.rpm |
| Kernel-lm-devel |
kenrnel-lt-devel-4.4.245-1.el7.elrepo.x86_64.rpm |
2.节点规划
| Hostname |
Ip |
内核版本 |
| k8s-master-01 |
192.168.12.11 |
4.4.245-1.el7.elrepo.x86_64 |
| K8s-node-01 |
192.168.12.12 |
4.4.245-1.el7.elrepo.x86_64 |
| K8s-node-02 |
192.168.12.13 |
4.4.245-1.el7.elrepo.x86_64 |
3. 关闭 selinux
sed -i 's#enforcing#disabled#g' /etc/sysconfig/selinux
setenforce 0
4. 关闭 swap 分区
一旦触发 swap,会导致系统性能急剧下降,所以一般情况下,K8S 要求关闭 swap 分区。
swapoff -a
sed -i.bak 's/^.*centos-swap/#&/g' /etc/fstab
echo 'KUBELET_EXTRA_ARGS="--fail-swap-on=false"' > /etc/sysconfig/kubelet
5. 配置国内 yum 源
默认情况下,CentOS 使用的是官方 yum 源,所以一般情况下在国内使用是非常慢,所以我们可以替换成国内的一些比较成熟的 yum 源,例如:清华大学镜像源,网易云镜像源等等。
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum makecache
yum update -y --exclud=kernel*
6.升级内核版本
由于 Docker 运行需要较新的系统内核功能,例如 ipvs 等等,所以一般情况下,我们需要使用 4.0+以上版本的系统内核。
wget https://elrepo.org/linux/kernel/el7/x86_64/RPMS/kernel-lt-4.4.245-1.el7.elrepo.x86_64.rpm
wget https://elrepo.org/linux/kernel/el7/x86_64/RPMS/kernel-lt-devel-4.4.245 1.el7.el repo.x86_64.rpm
yum localinstall -y kernel-lt* && grub2-set-default 0 && grub2-mkconfig -o /etc/grub2.cfg grubby --default-kernel
reboot
7.安装 ipvs
ipvs 是系统内核中的一个模块,其网络转发性能很高。一般情况下,我们首选 ipvs。
yum install -y conntrack-tools ipvsadm ipset conntrack libseccomp
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
ipvs_modules="ip_vs ip_vs_lc ip_vs_wlc ip_vs_rr ip_vs_wrr ip_vs_lblc ip_vs_lblcr ip_vs_dh ip_vs_sh ip_vs_fo ip_vs_nq ip_vs_sed ip_vs_ftp nf_conntrack"
for kernel_module in \${ipvs_modules};
do
/sbin/modinfo -F filename \${kernel_module} > /dev/null 2>&1
if [ $? -eq 0 ]; then
/sbin/modprobe \${kernel_module}
fi
done
EOF
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep ip_vs
8.内核参数优化
内核参数优化的主要目的是使其更适合 kubernetes 的正常运行。
cat > /etc/sysctl.d/k8s.conf << EOF
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
fs.may_detach_mounts = 1
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_watches=89100
fs.file-max=52706963
fs.nr_open=52706963
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp.keepaliv.probes = 3
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp.max_tw_buckets = 36000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp.max_orphans = 327680
net.ipv4.tcp_orphan_retries = 3
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.ip_conntrack_max = 65536
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.top_timestamps = 0
net.core.somaxconn = 16384
EOF
sysctl --system
9.安装基础软件
安装一些基础软件,是为了方便我们的日常使用。
yum install wget expect vim net-tools ntp bash-completion ipvsadm ipset jq iptables conntrack sysstat libseccomp -y
10.关闭防火墙
关闭防火墙是为了方便日常使用,不会给我们造成困扰。在生成环境中建议打开。
systemctl disable --now firewalld
11.安装 Docker
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install docker-ce -y
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json << 'EOF'
{
"registry-mirrors": ["https://8mh75mhz.mirror.aliyuncs.com"] }
EOF
sudo systemctl daemon-reload && systemctl restart docker && systemctl enable --now docker.service
wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.2.13-3.2.el7.x86_64.rpm
yum install containerd.io-1.2.13-3.2.el7.x86_64.rpm -y
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install docker-ce -y
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://8mh75mhz.mirror.aliyuncs.com"] }
EOF
sudo systemctl daemon-reload && systemctl restart docker && systemctl enable --now docker.service
12.同步集群时间
在集群当中,时间是一个很重要的概念,一旦集群当中某台机器时间跟集群时间不一致,可能会导致集群面临很多问题。所以,在部署集群之前,需要同步集群当中的所有机器的时间。
yum install ntp -y
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
echo 'Asia/Shanghai' > /etc/timezone ntpdate time2.aliyun.com
vim /etc/crontab
*/1 * * * * ntpdate time2.aliyun.com > /dev/null 2>&1
rpm -ivh http://mirrors.wlnmp.com/centos/wlnmp-release-centos.noarch.rpm yum install wntp -y
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
echo 'Asia/Shanghai' > /etc/timezone ntpdate time2.aliyun.com
vim /etc/crontab
*/1 * * * * ntpdate time2.aliyun.com > /dev/null 2>&1
13.配置 Kubernetes 源
cat > /etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
setenforce 0
yum install -y kubelet kubeadm kubectl systemctl enable kubelet && systemctl start kubelet
14.节点初始化
kubeadm init \
--image-repository=registry.cn-hangzhou.aliyuncs.com/k8sos \
--kubernetes-version=v1.18.8 \
--service-cidr=10.96.0.0/ \
--pod-network-cidr=10.244.0.0/16
14.1.配置kubernetes用户信息
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
14.2.增加命令提示
yum install -y bash-completion
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc
15.安装集群网络插件
kubernetes 需要使用第三方的网络插件来实现 kubernetes 的网络功能,这样一来,安装网络插件成为必要前提;第三方网络插件有多种,常用的有 flanneld、calico 和 cannel(flanneld+calico),不同的网络组件,都提供基本的网络功能,为各个 Node 节点提供 IP 网络等。
docker pull registry.cn-hangzhou.aliyuncs.com/k8sos/flannel:v0.12.0-amd64
docker tag registry.cn-hangzhou.aliyuncs.com/k8sos/flannel:v0.12.0-amd64 quay.io/coreos/flannel:v0.12.0-amd64
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
16.Node节点加入集群
kubeadm token create --print-join-command
kubeadm join 10.0.0.50:6443 --token 038qwm.hpoxkc1f2fkgti3r --discovery-token-ca-cert-hash sha256:edcd2c212be408f741e439abe304711ffb0adbb3bedbb1b93354bfdc3dd13b04
17.查看部署结果
kubectl get nodes -o wide
二、二进制部署篇
1、 环境初始化
1.1.软件系统版本
| 软件 |
版本 |
| Centos |
centos7.7 |
| Docker |
V19.03.12 |
| K8S |
V18.8.8 |
| Flannel |
V0.13.0 |
| Kernel-lm |
V4.18+ |
| Kernel-lm-devel |
V4.18+ |
| Haproxy |
V1.5.18 |
| Keepalived |
V1.3.5 |
1.2.集群规划
| Hostname |
Ip |
内网 IP |
内核版本 |
| kubernetes-master-01 |
192.168.12.50 |
172.16.0.50 |
4.4.245-1.el7.elrepo.x86_64 |
| kubernetes-master-02 |
192.168.12.51 |
172.16.0.51 |
4.4.245-1.el7.elrepo.x86_64 |
| kubernetes-master-03 |
192.168.12.52 |
172.16.0.52 |
4.4.245-1.el7.elrepo.x86_64 |
| kubernetes-node-01 |
192.168.12.53 |
172.16.0.53 |
4.4.245-1.el7.elrepo.x86_64 |
| kubernetes-node-02 |
192.168.12.54 |
172.16.0.54 |
4.4.245-1.el7.elrepo.x86_64 |
| kubernetes-master-vip |
|
172.16.0.55 |
VIP 虚拟节点 |
1.3.配置HOSTS解析
cat >> /etc/hosts <<EOF
192.168.1.50 kubernetes-master-01
192.168.1.51 kubernetes-master-02
192.168.1.52 kubernetes-master-03
192.168.1.53 kubernetes-node-01
192.168.1.54 kubernetes-node-02
192.168.1.55 kubernetes-master-vip
EOF
1.4.集群各节点免密登录
ssh-keygen -t rsa
for i in kubernetes-master-01 kubernetes-master-02 kubernetes-master-03 kubernetes-node-01 kubernetes-node-02 kubernetes-master-vip do;ssh-copy-id -i ~/.ssh/id_rsa.pub root@$i;done
1.5.关闭selinux
sed -i 's#enforcing#disabled#g' /etc/sysconfig/selinux
setenforce 0
1.6.关闭swap分区
一旦触发 swap,会导致系统性能急剧下降,所以一般情况下,K8S 要求关闭 swap 分区。
swapoff -a
sed -i.bak 's/^.*centos-swap/#&/g' /etc/fstab
echo 'KUBELET_EXTRA_ARGS="--fail-swap-on=false"' > /etc/sysconfig/kubelet
1.7.配置国内yum源
默认情况下,CentOS 使用的是官方 yum 源,所以一般情况下在国内使用是非常慢,所以我们可以替换成国内的一些比较成熟的 yum 源,例如:清华大学镜像源,网易云镜像源等等。
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum makecache
yum update -y --exclud=kernel*
1.8.升级内核版本
由于 Docker 运行需要较新的系统内核功能,例如 ipvs 等等,所以一般情况下,我们需要使用 4.0+以上版本的系统内核。
wget https://elrepo.org/linux/kernel/el7/x86_64/RPMS/kernel-lt-4.4.245-1.el7.elrepo.x86_64.rpm
wget https://elrepo.org/linux/kernel/el7/x86_64/RPMS/kernel-lt-devel-4.4.245-1.el7.elrepo.x86_64.rpm
yum localinstall -y kernel-lt* && grub2-set-default 0 && grub2-mkconfig -o /etc/grub2.cfg grubby --default-kernel
reboot
1.9.安装ipvs
ipvs 是系统内核中的一个模块,其网络转发性能很高。一般情况下,我们首选 ipvs。
yum install -y conntrack-tools ipvsadm ipset conntrack libseccomp
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
ipvs_modules="ip_vs ip_vs_lc ip_vs_wlc ip_vs_rr ip_vs_wrr ip_vs_lblc ip_vs_lblcr
ip_vs_dh ip_vs_sh ip_vs_fo ip_vs_nq ip_vs_sed ip_vs_ftp nf_conntrack"
for kernel_module in ${ipvs_modules}; do
/sbin/modinfo -F filename ${kernel_module} > /dev/null 2>&1
if [ 0 -eq 0 ]; then
/sbin/modprobe ${kernel_module}
fi
done
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep ip_vs
1.10、内核参数优化
内核参数优化的主要目的是使其更适合 kubernetes 的正常运行。
cat > /etc/sysctl.d/k8s.conf << EOF
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
fs.may_detach_mounts = 1
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_watches=89100
fs.file-max=52706963
fs.nr_open=52706963
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp.keepaliv.probes = 3
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp.max_tw_buckets = 36000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp.max_orphans = 327680
net.ipv4.tcp_orphan_retries = 3
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.ip_conntrack_max = 65536
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.top_timestamps = 0
net.core.somaxconn = 16384
EOF
sysctl --system
1.11、安装基础软件
安装一些基础软件,是为了方便我们的日常使用。
yum install wget expect vim net-tools ntp bash-completion ipvsadm ipset jq iptables conntrack sysstat libseccomp -y
1.12.关闭防火墙
关闭防火墙是为了方便日常使用,不会给我们造成困扰。在生成环境中建议打开。
systemctl disable --now firewalld
2、安装 Docker
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install docker-ce -y
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json << 'EOF'
{
"registry-mirrors": ["https://8mh75mhz.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload && systemctl restart docker && systemctl enable --now docker.service
wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.2.13-3.2.el7.x86_64.rpm
yum install containerd.io-1.2.13-3.2.el7.x86_64.rpm -y
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install docker-ce -y
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://8mh75mhz.mirror.aliyuncs.com"] }
EOF
sudo systemctl daemon-reload && systemctl restart docker && systemctl enable --now docker.service
3、同步集群时间
在集群当中,时间是一个很重要的概念,一旦集群当中某台机器时间跟集群时间不一致,可能会导致集群面临很多问题。所以,在部署集群之前,需要同步集群当中的所有机器的时间。
yum install ntp -y
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
echo 'Asia/Shanghai' > /etc/timezone ntpdate time2.aliyun.com
vim /etc/crontab
*/1 * * * * ntpdate time2.aliyun.com > /dev/null 2>&1
rpm -ivh http://mirrors.wlnmp.com/centos/wlnmp-release-centos.noarch.rpm yum install wntp -y
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
echo 'Asia/Shanghai' > /etc/timezone ntpdate time2.aliyun.com
vim /etc/crontab
*/1 * * * * ntpdate time2.aliyun.com > /dev/null 2>&1
4、集群证书
kubernetes 组件众多,这些组件之间通过 HTTP/GRPC 相互通信,以协同完成集群中应用的部署和管理工作。尤其是 master 节点,更是掌握着整个集群的操作。其安全就变得尤为重要了,在目前世面上最安全的,使用最广泛的就是数字证书。kubernetes 正是使用这种认证方式。
4.1.证书原理
4.2.安装cfssl证书生成工具
本次我们使用 cfssl 证书生成工具,这是一款把预先的证书机构、使用期等时间写在 json 文件里面会更加高效和自动化。cfssl 采用 go 语言编写,是一个开源的证书管理工具,cfssljson 用来从 cfssl 程序获取 json 输出,并将证书,密钥,csr 和 bundle 写入文件中。
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
chmod +x cfssljson_linux-amd64 chmod +x cfssl_linux-amd64
mv cfssljson_linux-amd64 cfssljson
mv cfssl_linux-amd64 cfssl
mv cfssljson cfssl /usr/local/bin
4.3. 创建集群根证书
从整个架构来看,集群环境中最重要的部分就是 etcd 和 API server。所以集群当中的证书都是针对 etcd 和 api server 来设置的。
所谓根证书,是 CA 认证中心与用户建立信任关系的基础,用户的数字证书必须有一个受信任的根证书,用户的数字证书才是有效的。从技术上讲,证书其实包含三部分,用户的信息,用户的公钥,以及证书签名。CA 负责数字证书的批审、发放、归档、撤销等功能,CA 颁发的数字证书拥有 CA 的数字签名,所以除了 CA 自身,其他机构无法不被察觉的改动。
mkdir -p /opt/cert/ca
cat > /opt/cert/ca/ca-config.json <<EOF
{
"signing":{
"default":{
"expiry":"8760h"
},
"profiles":{
"kubernetes":{
"usages":[
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry":"8760h"
}
}
}
}
EOF
4.3.1、证书详解
1. default 是默认策略,指定证书默认有效期是 1 年
2. profiles 是定义使用场景,这里只是 kubernetes,其实可以定义多个场景,分别指定不同的过期时间,使用场景等参数,后续签名证书时使用某个 profile;
3. signing: 表示该证书可用于签名其它证书,生成的 ca.pem 证书
4. server auth: 表示 client 可以用该 CA 对 server 提供的证书进行校验;
5. client auth: 表示 server 可以用该 CA 对 client 提供的证书进行验证。
4.4、 创建根CA证书签名请求文件
cat > /opt/cert/ca/ca-csr.json << EOF
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names":[{
"C": "CN",
"ST": "ShangHai",
"L": "ShangHai"
}]
}
EOF
4.4.1、证书详解
| 证书项 |
解释 |
| C |
国家 |
| ST |
省 |
| L |
城市 |
| O |
组织 |
| OU |
组织别名 |
4.5、生成证书
[root@kubernetes-master-01 ca]
2020/08/28 23:51:50 [INFO] generating a new CA key and certificate from CSR
2020/08/28 23:51:50 [INFO] generate received request
2020/08/28 23:51:50 [INFO] received CSR
2020/08/28 23:51:50 [INFO] generating key: rsa-2048
2020/08/28 23:51:50 [INFO] encoded CSR
2020/08/28 23:51:50 [INFO] signed certificate with serial number
66427391707536599498414068348802775591392574059
[root@kubernetes-master-01 ca]
总用量 20
-rw-r--r-- 1 root root 282 8月 28 23:41 ca-config.json
-rw-r--r-- 1 root root 1013 8月 28 23:51 ca.csr
-rw-r--r-- 1 root root 196 8月 28 23:41 ca-csr.json
-rw------- 1 root root 1675 8月 28 23:51 ca-key.pem
-rw-r--r-- 1 root root 1334 8月 28 23:51 ca.pem
4.5.1、参数详解
| 参数项 |
解释 |
| gencert |
生成新的 key(密钥)和签名证书 |
| --initca |
初始化一个新 CA 证书 |
5.部署 Etcd集群
Etcd 是基于 Raft 的分布式 key-value 存储系统,由 CoreOS 团队开发,常用于服务发现,共享配置,以及并发控制(如 leader 选举,分布式锁等等)。Kubernetes 使用 Etcd 进行状态和数据存储!
5.1、 ETCD集群规划
| ETCD 节点 |
IP |
| Etcd-01 |
172.16.0.50 |
| Etcd-02 |
172.16.0.51 |
| Etcd-03 |
172.16.0.52 |
5.2、 创建ETCD证书
mkdir -p /opt/cert/etcd && cd /opt/cert/etcd
cat > etcd-csr.json << EOF
{
"CN": "etcd",
"hosts": [
"127.0.0.1",
"192.168.1.50",
"192.168.1.51",
"192.168.1.52",
"192.168.1.53",
"192.168.1.54"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "ShangHai",
"L": "ShangHai"
}
]
}
EOF
5.3、 生成证书
[root@kubernetes-master-01 etcd]
2020/08/29 00:02:20 [INFO] generate received request
2020/08/29 00:02:20 [INFO] received CSR
2020/08/29 00:02:20 [INFO] generating key: rsa-2048
2020/08/29 00:02:20 [INFO] encoded CSR
2020/08/29 00:02:20 [INFO] signed certificate with serial number
71348009702526539124716993806163559962125770315
[root@kubernetes-master-01 etcd]
-rw-r--r-- 1 root root 1074 8月 29 00:02 etcd.csr
-rw-r--r-- 1 root root 352 8月 28 23:59 etcd-csr.json
-rw------- 1 root root 1675 8月 29 00:02 etcd-key.pem
-rw-r--r-- 1 root root 1460 8月 29 00:02 etcd.pem
5.3.1、参数详解
| 参数项 |
解释 |
| gencert |
生成新的key(密钥)和签名证书 |
| -initca |
初始化一个新ca |
| -ca-key |
指明ca证书 |
| -config |
指明ca的私钥文件 |
| -profile |
指明请求的json文件 |
| -ca |
与config中的profile对应,是根据config中的profile段来生成证书的相关信息 |
5.4、 分发证书
for ip in kubernetes-master-01 kubernetes-master-02 kubernetes-master-03;do ssh root@${ip} "mkdir -pv /etc/etcd/ssl" && scp ../ca/ca*.pem root@${ip}:/etc/etcd/ssl && scp ./etcd*.pem root@${ip}:/etc/etcd/ssl;done
for ip in kubernetes-master-01 kubernetes-master-02 kubernetes-master-03;do ssh root@${ip} "ls -l /etc/etcd/ssl";done
5.5、 部署 ETCD
wget https://mirrors.huaweicloud.com/etcd/v3.3.24/etcd-v3.3.24-linux-amd64.tar.gz
tar xf etcd-v3.3.24-linux-amd64
for i in kubernetes-master-02 kubernetes-master-01 kubernetes-master-03
do
scp ./etcd-v3.3.24-linux-amd64/etcd* root@$i:/usr/local/bin/
done
[root@kubernetes-master-01 etcd-v3.3.24-linux-amd64]
etcd Version: 3.3.24
Git SHA: bdd57848d
Go Version: go1.12.17
Go OS/Arch: linux/amd64
5.6、 注册 ETCD 服务
将 etcd 注册 systemd 服务主要是为了方便管理 ETCD。
mkdir -pv /etc/kubernetes/conf/etcd
ETCD_NAME=`hostname`
INTERNAL_IP=`hostname -i`
INITIAL_CLUSTER=kubernetes-master-01=https://192.168.1.50:2380,kubernetes-master-02=https://192.168.1.51:2380,kubernetes-master-03=https://192.168.1.52:2380
cat << EOF | sudo tee /usr/lib/systemd/system/etcd.service
[Unit]
Description=etcd
Documentation=https://github.com/coreos
[Service]
ExecStart=/usr/local/bin/etcd \\
--name ${ETCD_NAME} \\
--cert-file=/etc/etcd/ssl/etcd.pem \\
--key-file=/etc/etcd/ssl/etcd-key.pem \\
--peer-cert-file=/etc/etcd/ssl/etcd.pem \\
--peer-key-file=/etc/etcd/ssl/etcd-key.pem \\
--trusted-ca-file=/etc/etcd/ssl/ca.pem \\
--peer-trusted-ca-file=/etc/etcd/ssl/ca.pem \\
--peer-client-cert-auth \\
--client-cert-auth \\
--initial-advertise-peer-urls https://${INTERNAL_IP}:2380 \\
--listen-peer-urls https://${INTERNAL_IP}:2380 \\
--listen-client-urls https://${INTERNAL_IP}:2379,https://127.0.0.1:2379 \\
--advertise-client-urls https://${INTERNAL_IP}:2379 \\
--initial-cluster-token etcd-cluster \\
--initial-cluster ${INITIAL_CLUSTER} \\
--initial-cluster-state new \\
--data-dir=/var/lib/etcd
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
5.6.1、配置项详解
| 配置选项 |
选项说明 |
| name |
节点名称 |
| data-dir |
指定节点的数据存储目录 |
| listen-peer-urls |
与集群其它成员之间的通信地址 |
| listen-client-urls |
监听本地端口,对外提供服务的地址 |
| initial-advertise-peer-urls |
通告给集群其它节点,本地的对等 URL 地址 |
| advertise-client-urls |
客户端 URL,用于通告集群的其余部分信息 |
| initial-cluster |
集群中的所有信息节点 |
| initial-cluster-token |
集群的 token,整个集群中保持一致 |
| initial-cluster-state |
初始化集群状态,默认为 new |
| --cert-file |
客户端与服务器之间 TLS 证书文件的路径 |
| --key-file |
客户端与服务器之间 TLS 密钥文件的路径 |
| --peer-cert-file |
对等服务器 TLS 证书文件的路径 |
| --peer-key-file |
对等服务器 TLS 密钥文件的路径 |
| --trusted-ca-file |
签名 client 证书的 CA 证书,用于验证 client 证书 |
| --peer-trusted-ca-file |
签名对等服务器证书的 CA 证书。 |
| --trusted-ca-file |
签名 client 证书的 CA 证书,用于验证 client 证书 |
| --peer-trusted-ca-file |
签名对等服务器证书的 CA 证书。 |
5.6.2、启动 ETCD
systemctl enable --now etcd
5.6.3、测试 ETCD 集群
ETCDCTL_API=3 etcdctl \
--cacert=/etc/etcd/ssl/etcd.pem \
--cert=/etc/etcd/ssl/etcd.pem \
--key=/etc/etcd/ssl/etcd-key.pem \
--endpoints="https://192.168.1.50:2379,https://192.168.1.51:2379,https://192.168.1.52:2379" \
endpoint status --write-out='table'
ETCDCTL_API=3 etcdctl \
--cacert=/etc/etcd/ssl/etcd.pem \
--cert=/etc/etcd/ssl/etcd.pem \
--key=/etc/etcd/ssl/etcd-key.pem \
--endpoints="https://192.168.1.50:2379,https://192.168.1.51:2379,https://192.168.1.52:2379" \
member list --write-out='table'
6、 部署集群 master 节
6.1、 master 节点规划
| 主机名(角色) |
IP |
外网IP |
| Kubernetes-master-01 |
172.16.0.50 |
192.168.12.50 |
| Kubernetes-master-02 |
172.16.0.51 |
192.168.12.51 |
| Kubernetes-master-03 |
172.16.0.52 |
192.168.12.52 |
6.2、 创建集群证书
Master 节点是集群当中最为重要的一部分,组件众多,部署也最为复杂。
[root@kubernetes-master-01 k8s]
[root@kubernetes-master-01 k8s]
[root@kubernetes-master-01 k8s]
/opt/cert/k8s
[root@kubernetes-master-01 k8s]
{
"signing":{
"default":{
"expiry":"87600h"
},
"profiles":{
"kubernetes":{
"expiry":"87600h",
"usages":[
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF
6.3、 创建根证书签名
[root@kubernetes-master-01 k8s]
{
"CN":"kubernetes",
"key":{
"algo":"rsa",
"size":2048
},
"names":[
{
"C":"CN",
"L":"ShangHai",
"ST":"ShangHai"
}
]
}
EOF
[root@kubernetes-master-01 k8s]
-rw-r--r-- 1 root root 294 Sep 13 19:59 ca-config.json
-rw-r--r-- 1 root root 212 Sep 13 20:01 ca-csr.json
6.4、 生成根证书
[root@kubernetes-master-01k8s]
2020/09/13 20:01:45 [INFO] generating a new CA key and certificate from CSR
2020/09/13 20:01:45 [INFO] generate received request
2020/09/13 20:01:45 [INFO] received CSR
2020/09/13 20:01:45 [INFO] generating key: rsa-2048
2020/09/13 20:01:46 [INFO] encoded CSR
2020/09/13 20:01:46 [INFO] signed certificate with serial number
588993429584840635805985813644877690042550093427
[root@kubernetes-master-01 k8s]
-rw-r--r-- 1 root root 294 Sep 13 19:59 ca-config.json
-rw-r--r-- 1 root root 960 Sep 13 20:01 ca.csr
-rw-r--r-- 1 root root 212 Sep 13 20:01 ca-csr.json
-rw------- 1 root root 1679 Sep 13 20:01 ca-key.pem
-rw-r--r-- 1 root root 1273 Sep 13 20:01 ca.pem
6.5.签发kube-apiserver证书
6.5.1.创建 kube-apiserver 证书签名配置
[root@kubernetes-master-01 k8s]# cat > server-csr.json << EOF
{
"CN":"kubernetes",
"hosts":[
"127.0.0.1",
"192.168.1.50",
"192.168.1.51",
"192.168.1.52",
"192.168.1.55",
"10.96.0.1",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key":{
"algo":"rsa",
"size":2048
},
"names":[
{
"C":"CN",
"L":"ShangHai",
"ST":"ShangHai"
}
]
}
EOF
host:localhost 地址 + master 部署节点的 ip 地址 + etcd 节点的部署地址 + 负载均衡指定的 VIP(172.16.0.55) + service ip 段的第一个合法地址(10.96.0.1) + k8s 默认指定的一些地址。
6.5.2、生成证书
[root@kubernetes-master-01 k8s]
2020/08/29 12:29:41 [INFO] generate received request
2020/08/29 12:29:41 [INFO] received CSR
2020/08/29 12:29:41 [INFO] generating key: rsa-2048
2020/08/29 12:29:41 [INFO] encoded CSR
2020/08/29 12:29:41 [INFO] signed certificate with serial number
701177072439793091180552568331885323625122463841
6.6.签发kube-controller-manager证书
6.6.1、创建 kube-controller-manager 证书签名配置
cat > kube-controller-manager-csr.json << EOF
{
"CN":"system:kube-controller-manager",
"hosts":[
"127.0.0.1",
"192.168.1.50",
"192.168.1.51",
"192.168.1.52",
"192.168.1.55"
],
"key":{
"algo":"rsa",
"size":2048
},
"names":[
{
"C":"CN",
"L":"BeiJing",
"ST":"BeiJing",
"O":"system:kube-controller-manager",
"OU":"System"
}
]
}
EOF
6.6.2、生成证书
[root@kubernetes-master-01 k8s]
2020/08/29 12:40:21 [INFO] generate received request
2020/08/29 12:40:21 [INFO] received CSR
2020/08/29 12:40:21 [INFO] generating key: rsa-2048
2020/08/29 12:40:22 [INFO] encoded CSR
2020/08/29 12:40:22 [INFO] signed certificate with serial number
464924254532468215049650676040995556458619239240
6.7.签发kube-scheduler证书
6.7.1、创建 kube-scheduler 签名配置
cat > kube-scheduler-csr.json << EOF
{
"CN":"system:kube-scheduler",
"hosts":[
"127.0.0.1",
"192.168.1.50",
"192.168.1.51",
"192.168.1.52",
"192.168.1.55"
],
"key":{
"algo":"rsa",
"size":2048
},
"names":[
{
"C":"CN",
"L":"BeiJing",
"ST":"BeiJing",
"O":"system:kube-scheduler",
"OU":"System"
}
]
}
EOF
6.7.2、创建证书
[root@kubernetes-master-01 k8s]
2020/08/29 12:42:29 [INFO] generate received request
2020/08/29 12:42:29 [INFO] received CSR
2020/08/29 12:42:29 [INFO] generating key: rsa-2048
2020/08/29 12:42:29 [INFO] encoded CSR
2020/08/29 12:42:29 [INFO] signed certificate with serial number
420546069405900774170348492061478728854870171400
6.8.签发kube-proxy证书
6.8.1、创建 kube-proxy 证书签名配置
cat > kube-proxy-csr.json << EOF
{
"CN":"system:kube-proxy",
"hosts":[],
"key":{
"algo":"rsa",
"size":2048
},
"names":[
{
"C":"CN",
"L":"BeiJing",
"ST":"BeiJing",
"O":"system:kube-proxy",
"OU":"System"
}
]
}
EOF
6.8.2、生成证书
[root@kubernetes-master-01 k8s]
2020/08/29 12:45:11 [INFO] generate received request
2020/08/29 12:45:11 [INFO] received CSR
2020/08/29 12:45:11 [INFO] generating key: rsa-2048
2020/08/29 12:45:11 [INFO] encoded CSR
2020/08/29 12:45:11 [INFO] signed certificate with serial number
39717174368771783903269928946823692124470234079
2020/08/29 12:45: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").
6.9、 签发管理员用户证书
为了能让集群客户端工具安全的访问集群,所以要为集群客户端创建证书,使其具有所有的集群权限。
6.9.1、创建证书签名配置
cat > admin-csr.json << EOF
{
"CN":"admin",
"key":{
"algo":"rsa",
"size":2048
},
"names":[
{
"C":"CN",
"L":"BeiJing",
"ST":"BeiJing",
"O":"system:masters",
"OU":"System"
}
]
}
EOF
6.9.2、生成证书
[root@kubernetes-master-01 k8s]
2020/08/29 12:50:46 [INFO] generate received request
2020/08/29 12:50:46 [INFO] received CSR
2020/08/29 12:50:46 [INFO] generating key: rsa-2048
2020/08/29 12:50:46 [INFO] encoded CSR
2020/08/29 12:50:46 [INFO] signed certificate with serial number
247283053743606613190381870364866954196747322330
2020/08/29 12:50:46 [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").
6.10、颁发证书
Master 节点所需证书:ca、kube-apiservver、kube-controller-manager、kube-scheduler、用户证书、Etcd 证书。
6.10.1、 颁发 Master 节点证书
mkdir -pv /etc/kubernetes/ssl
cp -p ./{ca*pem,server*pem,kube-controller-manager*pem,kube-scheduler*.pem,kube-proxy*pem,admin*.pem} /etc/kubernetes/ssl
for i in kubernetes-master-02 kubernetes-master-03; do ssh root@$i "mkdir -pv /etc/kubernetes/ssl" && scp /etc/kubernetes/ssl/* root@$i:/etc/kubernetes/ssl
done
[root@kubernetes-master-01k8s]
> ssh root@$i "mkdir -pv /etc/kubernetes/ssl"
> scp /etc/kubernetes/ssl/* root@$i:/etc/kubernetes/ssl
> done mkdir: created directory ‘/etc/kubernetes/ssl’ admin-key.pem
100% 1679 562.2KB/s 00:00
admin.pem
100% 1359 67.5KB/s 00:00
ca-key.pem
100% 1679 39.5KB/s 00:00
ca.pem
100% 1273 335.6KB/s 00:00
kube-controller-manager-key.pem
100% 1679 489.6KB/s 00:00
kube-controller-manager.pem
100% 1472 69.4KB/s 00:00
kube-proxy-key.pem
100% 1679 646.6KB/s 00:00
kube-proxy.pem
100% 1379 672.8KB/s 00:00
kube-scheduler-key.pem
100% 1679 472.1KB/s 00:00
kube-scheduler.pem
100% 1448 82.7KB/s 00:00
server-key.pem
100% 1675 898.3KB/s 00:00
server.pem
100% 1554 2.2MB/s 00:00
mkdir: created directory ‘/etc/kubernetes/ssl’ admin-key.pem
100% 1679 826.3KB/s 00:00
admin.pem
100% 1359 1.1MB/s 00:00
ca-key.pem
100% 1679 127.4KB/s 00:00
ca.pem
100% 1273 50.8KB/s 00:00 kube-controller-manager-key.pem 100% 1679 197.7KB/s 00:00 kube-controller-manager.pem 100% 1472 833.7KB/s 00:00 kube-proxy-key.pem 100% 1679 294.6KB/s 00:00
kube-proxy.pem
100% 1379 94.9KB/s 00:00 kube-scheduler-key.pem 100% 1679 411.2KB/s 00:00 kube-scheduler.pem 100% 1448 430.4KB/s 00:00
server-key.pem
100% 1675 924.0KB/s 00:00
server.pem
100% 1554 126.6KB/s 00:00
6.11、部署master节点
6.11.1、 下载二进制组件
wget https://dl.k8s.io/v1.18.8/kubernetes-server-linux-amd64.tar.gz
wget https://dl.k8s.io/v1.18.8/kubernetes-client-linux-amd64.tar.gz
wget https://dl.k8s.io/v1.18.8/kubernetes-node-linux-amd64.tar.gz
[root@kubernetes-master-01 ~]
-rw-r--r-- 1 root root 13237066 8 月 29 02:51 kubernetes-client-linux-amd64.tar.gz
-rw-r--r-- 1 root root 97933232 8 月 29 02:51 kubernetes-node-linux-amd64.tar.gz
-rw-r--r-- 1 root root 363943527 8 月 29 02:51 kubernetes-server-linux-amd64.tar.gz
[root@kubernetes-master-01 k8s]
v1.18.8.1: Pulling from k8sos/k8s
75f829a71a1c: Pull complete 183ee8383f81: Pull complete a5955b997bb4: Pull complete 5401bb259bcd: Pull complete
0c05c4d60f48: Pull complete
6a216d9c9d7c: Pull complete
6711ab2c0ba7: Pull complete
3ff1975ab201: Pull complete
Digest: sha256:ee02569b218a4bab3f64a7be0b23a9feda8c6717e03f30da83f80387aa46e202
Status: Downloaded newer image for registry.cn-hangzhou.aliyuncs.com/k8sos/k8s:v1.18.8.1 registry.cn-
hangzhou.aliyuncs.com/k8sos/k8s:v1.18.8.1
6.11.2、 分发组件
[root@kubernetes-master-01 bin]
kube-apiserver 100% 115MB 94.7MB/s 00:01
kube-controller-manager 100% 105MB 87.8MB/s 00:01
kube-scheduler 100% 41MB 88.2MB/s 00:00
kubectl 100% 42MB 95.7MB/s 00:00
kube-apiserver 100% 115MB 118.4MB/s 00:00
kube-controller-manager 100% 105MB 107.3MB/s 00:00
kube-scheduler 100% 41MB 119.9MB/s 00:00
kubectl 100% 42MB 86.0MB/s 00:00
kube-apiserver 100% 115MB 120.2MB/s 00:00
kube-controller-manager 100% 105MB 108.1MB/s 00:00
kube-scheduler 100% 41MB 102.4MB/s 00:00
kubectl 100% 42MB 124.3MB/s 00:00
6.11.3、 创建集群配置文件
在 kubernetes 中,我们需要创建一个配置文件,用来配置集群、用户、命名空间及身份认证等信息。
6.11.3.1、创建kube-controller-manager.kubeconfig文件
cd && export KUBE_APISERVER="https://192.168.1.55:8443"
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=kube-controller-manager.kubeconfig
kubectl config set-credentials "kube-controller-manager" \
--client-certificate=/etc/kubernetes/ssl/kube-controller-manager.pem \
--client-key=/etc/kubernetes/ssl/kube-controller-manager-key.pem \
--embed-certs=true \
--kubeconfig=kube-controller-manager.kubeconfig
kubectl config set-context default \
--cluster=kubernetes \
--user="kube-controller-manager" \
--kubeconfig=kube-controller-manager.kubeconfig
kubectl config use-context default --kubeconfig=kube-controller-manager.kubeconfig
6.11.3.1.1、 参数详解
1. --certificate-authority:验证 kube-apiserver 证书的根证书。
2. --client-certificate、--client-key:刚生成的 kube-controller-manager 证书和私钥,连接 kube-apiserver 时使用。
3. --embed-certs=true:将 ca.pem 和 kube-controller-manager 证书内容嵌入到生成的 kubectl.kubeconfig 文件中
(不加时,写入的是证书文件路径)。
6.11.3.2、创建kube-scheduler.kubeconfig文件
export KUBE_APISERVER="https://192.168.1.55:8443"
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=kube-scheduler.kubeconfig
kubectl config set-credentials "kube-scheduler" \
--client-certificate=/etc/kubernetes/ssl/kube-scheduler.pem \
--client-key=/etc/kubernetes/ssl/kube-scheduler-key.pem \
--embed-certs=true \
--kubeconfig=kube-scheduler.kubeconfig
kubectl config set-context default \
--cluster=kubernetes \
--user="kube-scheduler" \
--kubeconfig=kube-scheduler.kubeconfig
kubectl config use-context default --kubeconfig=kube-scheduler.kubeconfig
6.11.3.3、创建kube-proxy.kubeconfig文件
export KUBE_APISERVER="https://192.168.1.55:8443"
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=kube-proxy.kubeconfig
kubectl config set-credentials "kube-proxy" \
--client-certificate=/etc/kubernetes/ssl/kube-proxy.pem \
--client-key=/etc/kubernetes/ssl/kube-proxy-key.pem \
--embed-certs=true \
--kubeconfig=kube-proxy.kubeconfig
kubectl config set-context default \
--cluster=kubernetes \
--user="kube-proxy" \
--kubeconfig=kube-proxy.kubeconfig
kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
6.11.3.4、创建admin.kubeconfig文件
export KUBE_APISERVER="https://192.168.1.55:8443"
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=admin.kubeconfig
kubectl config set-credentials "admin" \
--client-certificate=/etc/kubernetes/ssl/admin.pem \
--client-key=/etc/kubernetes/ssl/admin-key.pem \
--embed-certs=true \
--kubeconfig=admin.kubeconfig
kubectl config set-context default \
--cluster=kubernetes \
--user="admin" \
--kubeconfig=admin.kubeconfig
kubectl config use-context default --kubeconfig=admin.kubeconfig
6.11.4、 分发集群配置文件
[root@kubernetes-master-01 ~]
token.csv 100% 84 662.0KB/s 00:00
kube-scheduler.kubeconfig 100% 6159 47.1MB/s 00:00 kube-controller-manager.kubeconfig 100% 6209 49.4MB/s
00:00
admin.conf 100% 6021 51.0MB/s 00:00
kube-proxy.kubeconfig 100% 6059 52.7MB/s 00:00 kubelet-bootstrap.kubeconfig 100% 1985 25.0MB/s
00:00
token.csv 100% 84 350.5KB/s 00:00
kube-scheduler.kubeconfig 100% 6159 20.0MB/s 00:00 kube-controller-manager.kubeconfig 100% 6209 20.7MB/s
00:00
admin.conf 100% 6021 23.4MB/s 00:00
kube-proxy.kubeconfig 100% 6059 20.0MB/s 00:00 kubelet-bootstrap.kubeconfig 100%1985 4.4MB/s 00:00
token.csv 100% 84 411.0KB/s 00:00
kube-scheduler.kubeconfig 100% 6159 19.6MB/s 00:00 kube-controller-manager.kubeconfig 100% 6209 21.4MB/s
00:00
admin.conf 100% 6021 19.9MB/s 00:00
kube-proxy.kubeconfig 100% 6059 20.1MB/s 00:00 kubelet-bootstrap.kubeconfig 100%1985 9.8MB/s 00:00
6.11.5、 部署组件
6.11.5.1、部署api-server
创建 kube-apiserver 服务配置文件(三个节点都要执行,不能复制,注意 api server IP)。
KUBE_APISERVER_IP=`hostname -i`
cat > /etc/kubernetes/cfg/kube-apiserver.conf << EOF
KUBE_APISERVER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/var/log/kubernetes \\
--advertise-address=${KUBE_APISERVER_IP} \\
--default-not-ready-toleration-seconds=360 \\
--default-unreachable-toleration-seconds=360 \\
--max-mutating-requests-inflight=2000 \\
--max-requests-inflight=4000 \\
--default-watch-cache-size=200 \\
--delete-collection-workers=2 \\
--bind-address=0.0.0.0 \\
--secure-port=6443 \\
--allow-privileged=true \\
--service-cluster-ip-range=10.96.0.0/16 \\
--service-node-port-range=10-52767 \\
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,Resourc eQuota,NodeRestriction \\
--authorization-mode=RBAC,Node \\
--enable-bootstrap-token-auth=true \\
--token-auth-file=/etc/kubernetes/cfg/token.csv \\
--kubelet-client-certificate=/etc/kubernetes/ssl/server.pem \\
--kubelet-client-key=/etc/kubernetes/ssl/server-key.pem \\
--tls-cert-file=/etc/kubernetes/ssl/server.pem \\
--tls-private-key-file=/etc/kubernetes/ssl/server-key.pem \\
--client-ca-file=/etc/kubernetes/ssl/ca.pem \\
--service-account-key-file=/etc/kubernetes/ssl/ca-key.pem \\
--audit-log-maxage=30 \\
--audit-log-maxbackup=3 \\
--audit-log-maxsize=100 \\
--audit-log-path=/var/log/kubernetes/k8s-audit.log \\
--etcd-servers=https://192.168.1.50:2379,https://192.168.1.51:2379,https://192.168.1.52:2379 \\
--etcd-cafile=/etc/etcd/ssl/ca.pem \\
--etcd-certfile=/etc/etcd/ssl/etcd.pem \\
--etcd-keyfile=/etc/etcd/ssl/etcd-key.pem"
EOF
6.11.5.1.1、 参数详解
| 配置选项 |
选项说明 |
| --logtostderr=false |
输出日志到文件中,不输出到标准错误控制台 |
| --v=2 |
指定输出日志的级别 |
| --advertise-address |
向集群成员通知 apiserver 消息的 IP 地址 |
| --etcd-servers |
连接的 etcd 服务器列表 |
| --etcd-cafile |
用于 etcd 通信的 SSL CA 文件 |
| --etcd-certfile |
用于 etcd 通信的的 SSL 证书文件 |
| --etcd-keyfile |
用于 etcd 通信的 SSL 密钥文件 |
| --service-cluster-ip-range |
Service 网络地址分配 |
| --bind-address |
监听 --seure-port 的 IP 地址,如果为空,则将使用所有接口 (0.0.0.0) |
| --secure-port=6443 |
用于监听具有认证授权功能的 HTTPS 协议的端口,默认值是 6443 |
| --allow-privileged |
是否启用授权功能 |
| --service-node-port-range |
Service 使用的端口范围 |
| --default-not-ready-toleration-seconds |
表示 notReady 状态的容忍度秒数 |
| --default-unreachable-toleration-seconds |
表示 unreachable 状态的容忍度秒数: |
| --max-mutating-requests-inflight=2000 |
在给定时间内进行中可变请求的最大数量,0 值表示没有限制(默认值 200) |
| --default-watch-cache-size=200 |
默认监视缓存大小,0 表示对于没有设置默认监视大小的资源,将禁用监视缓存 |
| --delete-collection-workers=2 |
用于 DeleteCollection 调用的工作者数量,这被用于加速 namespace 的清理( 默认值 1) |
| --enable-admission-plugins |
资源限制的相关配置 |
| --authorization-mode |
在安全端口上进行权限验证的插件的顺序列表,以逗号分隔的列表。 |
6.11.5.1.2、 注册 kube-apiserver 服务
cat > /usr/lib/systemd/system/kube-apiserver.service << EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes After=network.target
[Service]
EnvironmentFile=/etc/kubernetes/cfg/kube-apiserver.conf
ExecStart=/usr/local/bin/kube-apiserver \$KUBE_APISERVER_OPTS
Restart=on-failure
RestartSec=10
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
6.11.5.1.3、 分发 kube-apiserver 服务脚本
for i in kubernetes-master-02 kubernetes-master-03; do scp /usr/lib/systemd/system/kube-apiserver.service root@$i:/usr/lib/systemd/system/kube-apiserver.service;done
6.11.5.1.4、 启动
mkdir -p /var/log/kubernetes/
systemctl daemon-reload
systemctl enable --now kube-apiserver
6.11.5.2、高可用部署api-server
负载均衡器有很多种,只要能实现 api-server 高可用都行,这里我们采用官方推荐的 haproxy + keepalived。
6.11.5.2.1、 安装高可用软件
yum install -y keepalived haproxy
6.11.5.2.2、 配置 haproxy 服务
cat > /etc/haproxy/haproxy.cfg <<EOF
global
maxconn 2000
ulimit-n 16384
log 127.0.0.1 local0 err
stats timeout 30s
defaults
log global
mode http
option httplog
timeout connect 5000
timeout client 50000
timeout server 50000
timeout http-request 15s
timeout http-keep-alive 15s
frontend monitor-in
bind *:33305
mode http
option httplog
monitor-uri /monitor
listen stats
bind *:8006
mode http
stats enable
stats hide-version
stats uri /stats
stats refresh 30s
stats realm Haproxy\ Statistics
stats auth admin:admin
frontend k8s-master
bind 0.0.0.0:8443
bind 127.0.0.1:8443
mode tcp
option tcplog
tcp-request inspect-delay 5s
default_backend k8s-master
backend k8s-master
mode tcp
option tcplog
option tcp-check
balance roundrobin
default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100
server kubernetes-master-01 192.168.1.50:6443 check inter 2000 fall 2 rise 2 weight 100
server kubernetes-master-02 192.168.1.51:6443 check inter 2000 fall 2 rise 2 weight 100
server kubernetes-master-03 192.168.1.52:6443 check inter 2000 fall 2 rise 2 weight 100
EOF
6.11.5.2.3、 分发至其他节点
for i in kubernetes-master-01 kubernetes-master-02 kubernetes-master-03;
do
ssh root@$i "mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg_bak"
scp haproxy.cfg root@$i:/etc/haproxy/haproxy.cfg
done
6.11.5.2.4、 haproxy 常见链接错
setsebool -P haproxy_connect_any=1
6.11.5.2.5、 配置 keepalived 服务
mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf_bak
cd /etc/keepalived
cat > /etc/keepalived/keepalived.conf <<EOF
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL
}
vrrp_script chk_kubernetes {
script "/etc/keepalived/check_kubernetes.sh"
interval 2
weight -5
fall 3
rise 2
}
vrrp_instance VI_1 {
state MASTER
interface eth0
mcast_src_ip 172.16.0.50
virtual_router_id 51
priority 100
advert_int 2
authentication {
auth_type PASS
auth_pass K8SHA_KA_AUTH
}
virtual_ipaddress {
172.16.0.55
}
}
EOF
6.11.5.2.6、 分发 keepalived 配置文件
for i in kubernetes-master-02 kubernetes-master-03;
do
ssh root@$i "mv /etc/keepalived/keepalived.conf
/etc/keepalived/keepalived.conf_bak"
scp /etc/keepalived/keepalived.conf root@$i:/etc/keepalived/keepalived.conf
done
6.11.5.2.6.1、 配置 kubernetes-master-02 节点
sed -i 's#state MASTER#state BACKUP#g' /etc/keepalived/keepalived.conf
sed -i 's#172.16.0.50#172.16.0.51#g' /etc/keepalived/keepalived.conf
sed -i 's#priority 100#priority 90#g' /etc/keepalived/keepalived.conf
6.11.5.2.6.2、 配置 kubernetes-master-03 节点
sed -i 's#state MASTER#state BACKUP#g' /etc/keepalived/keepalived.conf
sed -i 's#172.16.0.50#172.16.0.52#g' /etc/keepalived/keepalived.conf
sed -i 's#priority 100#priority 98#g' /etc/keepalived/keepalived.conf
6.11.5.2.6.3、 设置监控检查脚本
cat > /etc/keepalived/check_kubernetes.sh <<EOF
#!/bin/bash
function chech_kubernetes() {
for ((i=0;i<5;i++));do
apiserver_pid_id=$(pgrep kube-apiserver)
if [[ ! -z $apiserver_pid_id ]];then
return
else
sleep 2
fi
apiserver_pid_id=0
done
}
check_kubernetes
if [[ $apiserver_pid_id -eq 0 ]];then
/usr/bin/systemctl stop keepalived
exit 1
else
exit 0
fi
EOF
chmod +x /etc/keepalived/check_kubernetes.sh
6.11.5.2.6.4、 启动 keeplived 和 haproxy 服务
systemctl enable --now keepalived haproxy
6.11.5.3、 部署 kube-controller-manager 服务
Controller Manager 作为集群内部的管理控制中心,负责集群内的 Node、Pod 副本、服务端点(Endpoint)、命名空间(Namespace)、服务账号(ServiceAccount)、资源定额(ResourceQuota)的管理,当某个 Node 意外宕机时,Controller Manager 会及时发现并执行自动化修复流程,确保集群始终处于预期的工作状态。如果多个控制器管理器同时生效,则会有一致性问题,所以 kube-controller-manager 的高可用,只能是主备模式,而kubernetes 集群是采用租赁锁实现 leader 选举,需要在启动参数中加入 --leader-elect=true。
6.11.5.3.1、 创建 kube-controller-manager 配置文件
cat > /etc/kubernetes/cfg/kube-controller-manager.conf << EOF
KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/var/log/kubernetes \\
--leader-elect=true \\
--cluster-name=kubernetes \\
--bind-address=127.0.0.1 \\
--allocate-node-cidrs=true \\
--cluster-cidr=10.244.0.0/12 \\
--service-cluster-ip-range=10.96.0.0/16 \\
--cluster-signing-cert-file=/etc/kubernetes/ssl/ca.pem \\
--cluster-signing-key-file=/etc/kubernetes/ssl/ca-key.pem \\
--root-ca-file=/etc/kubernetes/ssl/ca.pem \\
--service-account-private-key-file=/etc/kubernetes/ssl/ca-key.pem \\
--kubeconfig=/etc/kubernetes/cfg/kube-controller-manager.kubeconfig \\
--tls-cert-file=/etc/kubernetes/ssl/kube-controller-manager.pem \\
--tls-private-key-file=/etc/kubernetes/ssl/kube-controller-manager-key.pem \\
--experimental-cluster-signing-duration=87600h0m0s \\
--controllers=*,bootstrapsigner,tokencleaner \\
--use-service-account-credentials=true \\
--node-monitor-grace-period=10s \\
--horizontal-pod-autoscaler-use-rest-clients=true"
EOF
6.11.5.3.2、 配置文件详解
| 配置选项 |
选项意义 |
| --leader-elect |
高可用时启用选举功能。 |
| --master |
通过本地菲安全端口8080链接apiserver |
| --allocate-node-cidrs |
是否应在 node 节点上分配和设置 Pod 的 CID |
| --cluster-cidr |
Controller Manager 在启动时如果设置了--cluster-cidr 参 数,防止不同的节点的 CIDR 地址发生冲突 |
| --service-cluster-ip-range |
集群 Services 的 CIDR 范围 |
| --cluster-signing-cert-file |
指定用于集群签发的所有集群范围内证书文件(根证书 文件) |
| --cluster-signing-key-file |
指定集群签发证书的 key |
| --root-ca-file |
如果设置,该根证书权限将包含 service acount 的 toker secret,这必须是一个有效的 PEM 编码 CA 包 |
| --service-account-private-key-file |
包含用于签署 service account token 的 PEM 编码 RSA 或 者 ECDSA 私钥的文件名 |
| --experimental-cluster-signing-duration |
证书签发时间 |
| --bind-address |
监控地址 |
6.11.5.3.3、 注册 kube-controller-manager 服务
cat > /usr/lib/systemd/system/kube-controller-manager.service << EOF
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
After=network.target
[Service]
EnvironmentFile=/etc/kubernetes/cfg/kube-controller-manager.conf
ExecStart=/usr/local/bin/kube-controller-manager \$KUBE_CONTROLLER_MANAGER_OPTS
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
6.11.5.3.4、 分发脚本
for i in kubernetes-master-02 kubernetes-master-03;do scp /etc/kubernetes/cfg/kube-controller-manager.conf root@$i:/etc/kubernetes/cfg && scp /usr/lib/systemd/system/kube-controller-manager.service root@$i:/usr/lib/systemd/system/kube-controller-manager.service;done
6.11.5.3.5、 启动
[root@kubernetes-master-01 ~]
[root@kubernetes-master-01 ~]
[root@kubernetes-master-01 ~]
● kube-controller-manager.service - Kubernetes Controller Manager
Loaded: loaded (/usr/lib/systemd/system/kube-controller-manager.service; enabled;
vendor preset: disabled)
Active: active (running) since 一 2020-11-16 14:55:46 CST; 1 weeks 3 days ago
Docs: https://github.com/kubernetes/kubernetes
Main PID: 3854 (kube-controller)
CGroup: /system.slice/kube-controller-manager.service
└─3854 /usr/local/bin/kube-controller-manager --logtostderr=false --v=2
--log-dir=/var/log/kubernetes --leader-elect=true --cluster-name=kubernetes
--bind-address=127.0.0.1 --allocate-node...
11 月 16 15:09:40 kubernetes-master-01 kube-controller-manager[3854]: E1116
15:09:40.495403 3854 leaderelection.go:320] error retrieving resource lock
kube-system/kube-controller-manage...ion refused
11 月 16 15:09:44 kubernetes-master-01 kube-controller-manager[3854]: E1116
15:09:44.027037 3854 leaderelection.go:320] error retrieving resource lock
kube-system/kube-controller-manage...ion refused
11 月 16 15:09:46 kubernetes-master-01 kube-controller-manager[3854]: E1116
15:09:46.932321 3854 leaderelection.go:320] error retrieving resource lock
kube-system/kube-controller-manage...ion refused
11 月 16 15:09:50 kubernetes-master-01 kube-controller-manager[3854]: E1116
15:09:50.454578 3854 leaderelection.go:320] error retrieving resource lock
kube-system/kube-controller-manage...ion refused
11 月 16 15:09:52 kubernetes-master-01 kube-controller-manager[3854]: E1116
15:09:52.989980 3854 leaderelection.go:320] error retrieving resource lock
kube-system/kube-controller-manage...ion refused
11 月 16 15:09:57 kubernetes-master-01 kube-controller-manager[3854]: E1116
15:09:57.045952 3854 leaderelection.go:320] error retrieving resource lock
kube-system/kube-controller-manage...ion refused
11 月 16 15:10:01 kubernetes-master-01 kube-controller-manager[3854]: E1116
15:10:01.147034 3854 leaderelection.go:320] error retrieving resource lock
kube-system/kube-controller-manage...ion refused
11 月 16 15:10:05 kubernetes-master-01 kube-controller-manager[3854]: E1116
15:10:05.294025 3854 core.go:89] Failed to start service controller: WARNING: no
cloud provider provided, ser...r will fail
11 月 16 15:10:08 kubernetes-master-01 kube-controller-manager[3854]: E1116
15:10:08.901810 3854 core.go:229] failed to start cloud node lifecycle controller:
no cloud provider provided
11 月 17 14:34:50 kubernetes-master-01 kube-controller-manager[3854]: E1117
14:34:50.107439 3854 tokens_controller.go:261] error synchronizing
serviceaccount ingress-nginx/default: secr... terminated
Hint: Some lines were ellipsized, use -l to show in full.
6.11.5.4、 部署 kube-scheduler 服务
kube-scheduler 是 Kubernetes 集群的默认调度器,并且是集群 控制面 的一部分。对每一个新创建的 Pod 或者是未被调度的 Pod,kube-scheduler 会过滤所有的 node,然后选择一个最优的 Node 去运行这个 Pod。kube-scheduler 调度器是一个策略丰富、拓扑感知、工作负载特定的功能,调度器显著影响可用性、性能和容量。调度器需要考虑个人和集体的资源要求、服务质量要求、硬件/软件/政策约束、亲和力和反亲和力规范、数据局
部性、负载间干扰、完成期限等。工作负载特定的要求必要时将通过 API 暴露。
6.11.5.4.1、 创建 kube-scheduler 配置文件
cat > /etc/kubernetes/cfg/kube-scheduler.conf << EOF
KUBE_SCHEDULER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/var/log/kubernetes \\
--kubeconfig=/etc/kubernetes/cfg/kube-scheduler.kubeconfig \\
--leader-elect=true \\
--master=http://127.0.0.1:8080 \\
--bind-address=127.0.0.1 "
EOF
6.11.5.4.2、 创建启动脚本
cat > /usr/lib/systemd/system/kube-scheduler.service << EOF
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
After=network.target
[Service]
EnvironmentFile=/etc/kubernetes/cfg/kube-scheduler.conf
ExecStart=/usr/local/bin/kube-scheduler \$KUBE_SCHEDULER_OPTS
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
6.11.5.4.3、 分发配置文件
for ip in kubernetes-master-02 kubernetes-master-03;do scp /usr/lib/systemd/system/kube-scheduler.service root@${ip}:/usr/lib/systemd/system && scp /etc/kubernetes/cfg/kube-scheduler.conf root@${ip}:/etc/kubernetes/cfg;done
6.11.5.4.4、 启动
systemctl daemon-reload
systemctl enable --now kube-scheduler
6.11.5.5、 查看集群状态
[root@kubernetes-master-01 ~]
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-0 Healthy {"health":"true"}
etcd-1 Healthy {"health":"true"}
etcd-2 Healthy {"health":"true"}
6.11.5.6、 配置 TLS bootstrapping
TLS bootstrapping 是用来简化管理员配置 kubelet 与 apiserver 双向加密通信的配置步骤的一种机制。当集群开启了 TLS 认证后,每个节点的 kubelet 组件都要使用由 apiserver 使用的 CA 签发的有效证书才能与apiserver 通讯,此时如果有很多个节点都需要单独签署证书那将变得非常繁琐且极易出错,导致集群不稳。TLS bootstrapping 功能就是让 node 节点上的 kubelet 组件先使用一个预定的低权限用户连接到 apiserver,然后向 apiserver 申请证书,由 apiserver 动态签署颁发到 Node 节点,实现证书签署自动化。
6.11.5.6.1、 生成 TLS bootstrapping 所需 token
TLS_BOOTSTRAPPING_TOKEN=`head -c 16 /dev/urandom | od -An -t x | tr -d ' '`
cat > token.csv << EOF
${TLS_BOOTSTRAPPING_TOKEN},kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF
[root@kubernetes-master-01 k8s]
[root@kubernetes-master-01 k8s]
[root@kubernetes-master-01 k8s]
${TLS_BOOTSTRAPPING_TOKEN},kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF
[root@kubernetes-master-01 k8s]
1b076dcc88e04d64c3a9e7d7a1586fe5,kubelet-bootstrap,10001,"system:kubelet-bootstrap"
6.11.5.6.2、 创建 TLS Bootstrapping 集群配置文件
在 kubernetes 中,我们需要创建一个配置文件,用来配置集群、用户、命名空间及身份认证等信息。
export KUBE_APISERVER="https://192.168.1.55:8443"
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=kubelet-bootstrap.kubeconfig
kubectl config set-credentials "kubelet-bootstrap" \
--token=174e85dff021111a0c6370155b3c3284 \
--kubeconfig=kubelet-bootstrap.kubeconfig
kubectl config set-context default \
--cluster=kubernetes \
--user="kubelet-bootstrap" \
--kubeconfig=kubelet-bootstrap.kubeconfig
kubectl config use-context default --kubeconfig=kubelet-bootstrap.kubeconfig
6.11.5.6.3、 创建 TLS 匿名用户
kubectl create clusterrolebinding kubelet-bootstrap \
--clusterrole=system:node-bootstrapper \
--user=kubelet-bootstrap
6.11.5.7、 部署 kubelet 服务
6.11.5.7.1、 创建 kubelet 配置
KUBE_HOSTNAME=`hostname`
cat > /etc/kubernetes/cfg/kubelet.conf << EOF
KUBELET_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/var/log/kubernetes \\
--hostname-override=${KUBE_HOSTNAME} \\
--container-runtime=docker \\
--kubeconfig=/etc/kubernetes/cfg/kubelet.kubeconfig \\
--bootstrap-kubeconfig=/etc/kubernetes/cfg/kubelet-bootstrap.kubeconfig \\
--config=/etc/kubernetes/cfg/kubelet-config.yml \\
--cert-dir=/etc/kubernetes/ssl \\
--image-pull-progress-deadline=15m \\
--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/k8sos/pause:3.2"
EOF
6.11.5.7.1.1、 配置详解
| 配置选项 |
选项意义 |
| --hostname-override |
用 来 配 置 该 节 点 在 集 群 中 显 示 的 主 机 名 , kubelet 设 置 了 -–hostname-override 参数后,kube-proxy 也需要设置,否则会出现找 不到 Node 的情况 |
| --container-runtime |
指定容器运行时引擎 |
| --kubeconfig |
kubelet 作 为 客 户 端 使 用 的 kubeconfig 认 证 文 件 , 此 文 件 是 由 kube-controller-mananger 自动生成的 |
| --bootstrap-kubeconfig |
指定令牌认证文件 |
| --config |
指定 kubelet 配置文件 |
| --cert-dir |
设置 kube-controller-manager 生成证书和私钥的目录 |
| --image-pull-progress-deadline |
镜像拉取进度最大时间,如果在这段时间拉取镜像没有任何进展,将 取消拉取,默认:1m0s |
| --pod-infra-container-image |
每个 pod 中的 network/ipc 名称空间容器将使用的镜像 |
6.11.5.7.2、 创建 kubelet-config 配置文件
cat > /etc/kubernetes/cfg/kubelet-config.yml << EOF
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: 192.168.1.50
port: 10250
readOnlyPort: 10255
cgroupDriver: cgroupfs
clusterDNS:
- 10.96.0.2
clusterDomain: cluster.local
failSwapOn: false
authentication:
anonymous:
enabled: false
webhook:
cacheTTL: 2m0s
enabled: true
x509:
clientCAFile: /etc/kubernetes/ssl/ca.pem
authorization:
mode: Webhook
webhook:
cacheAuthorizedTTL: 5m0s
cacheUnauthorizedTTL: 30s
evictionHard:
imagefs.available: 15%
memory.available: 100Mi
nodefs.available: 10%
nodefs.inodesFree: 5%
maxOpenFiles: 1000000
maxPods: 110
EOF
6.11.5.7.2.1、 配置详解
| 配置选项 |
选项意义 |
| address |
kubelet 服务监听的地址 |
| port |
kubelet 服务的端口,默认 10250 |
| readOnlyPort |
没有认证/授权的只读 kubelet 服务端口 ,设置为 0 表示禁用,默认 10255 |
| clusterDNS |
DNS 服务器的 IP 地址列表 |
| clusterDomain |
集群域名, kubelet 将配置所有容器除了主机搜索域还将搜索当前域 |
6.11.5.7.3、 创建 kubelet 启动脚本
cat > /usr/lib/systemd/system/kubelet.service << EOF
[Unit]
Description=Kubernetes Kubelet
After=docker.service
[Service]
EnvironmentFile=/etc/kubernetes/cfg/kubelet.conf
ExecStart=/usr/local/bin/kubelet \$KUBELET_OPTS
Restart=on-failure
RestartSec=10
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
6.11.5.7.4、 分发配置文件
for ip in kubernetes-master-01 kubernetes-master-02 kubernetes-master-03 ;do scp /etc/kubernetes/cfg/{kubelet-config.yml,kubelet.conf} root@${ip}:/etc/kubernetes/cfg && scp /usr/lib/systemd/system/kubelet.service root@${ip}:/usr/lib/systemd/system;done
6.11.5.7.5、 配置文件处理
sed -i 's#master-01#master-02#g' /etc/kubernetes/cfg/kubelet.conf
sed -i 's#172.16.0.50#172.16.0.51#g' /etc/kubernetes/cfg/kubelet-config.yml
sed -i 's#master-01#master-03#g' /etc/kubernetes/cfg/kubelet.conf
sed -i 's#172.16.0.50#172.16.0.52#g' /etc/kubernetes/cfg/kubelet-config.yml
6.11.5.7.6、 开启 kubelet 服务
systemctl daemon-reload && systemctl enable --now kubelet && systemctl status kubelet.service
6.11.5.8、 配置 kube-proxy 服务
kube-proxy 是 Kubernetes 的核心组件,部署在每个 Node 节点上,它是实现 Kubernetes Service 的通信与负载均衡机制的重要组件; kube-proxy 负责为 Pod 创建代理服务,从 apiserver 获取所有 server 信息,并根据 server 信息创建代理服务,实现 server 到 Pod 的请求路由和转发,从而实现 K8s 层级的虚拟转发网络。
6.11.5.8.1、 创建 kube-proxy 配置文件
cat > /etc/kubernetes/cfg/kube-proxy.conf << EOF
KUBE_PROXY_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/var/log/kubernetes \\
--config=/etc/kubernetes/cfg/kube-proxy-config.yml"
EOF
6.11.5.8.2、 创建 kube-proxy-config 配置文件
cat > /etc/kubernetes/cfg/kube-proxy-config.yml << EOF
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 192.168.1.52
healthzBindAddress: 192.168.1.52:10256
metricsBindAddress: 192.168.1.52:10249
clientConnection:
burst: 200
kubeconfig: /etc/kubernetes/cfg/kube-proxy.kubeconfig
qps: 100
hostnameOverride: kubernetes-master-03
clusterCIDR: 10.96.0.0/16
enableProfiling: true
mode: "ipvs"
kubeProxyIPTablesConfiguration:
masqueradeAll: false
kubeProxyIPVSConfiguration:
scheduler: rr
excludeCIDRs: []
EOF
6.11.5.8.2.1、 配置文件详解
| 选项配置 |
选项意义 |
| clientConnection |
与 kube-apiserver 交互时的参数设置 |
| burst: 200 |
临时允许该事件记录值超过 qps 设定值 |
| kubeconfig |
kube-proxy 客户端连接 kube-apiserver 的 kubeconfig 文件路径设置 |
| qps: 100 |
与 kube-apiserver 交互时的 QPS,默认值 5 |
| bindAddress |
kube-proxy 监听地址 |
| healthzBindAddress |
用于检查服务的 IP 地址和端口 |
| metricsBindAddress |
metrics 服务的 ip 地址和端口。默认:127.0.0.1:10249 |
| clusterCIDR |
kube-proxy 根据 --cluster-cidr 判断集群内部和外部流量,指定 --cluster-cidr 或 --masquerade-all 选项后 kube-proxy 才会对访问 Service IP 的请求做 SNAT |
| hostnameOverride |
参数值必须与 kubelet 的值一致,否则 kube-proxy 启动后会找不到该 Node,从而不会创建任何 ipvs 规则; |
| masqueradeAll |
如果使用纯 iptables 代理,SNAT 所有通过服务集群 ip 发送的通信 |
| mode |
使用 ipvs 模式 |
| scheduler |
当 proxy 为 ipvs 模式时,ipvs 调度类型 |
6.11.5.8.3、 创建 kube-proxy 启动脚本
cat > /usr/lib/systemd/system/kube-proxy.service << EOF
[Unit]
Description=Kubernetes Proxy After=network.target
[Service]
EnvironmentFile=/etc/kubernetes/cfg/kube-proxy.conf
ExecStart=/usr/local/bin/kube-proxy \$KUBE_PROXY_OPTS
Restart=on-failure
RestartSec=10
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
6.11.5.8.4、 分发配置文件
for ip in kubernetes-master-01 kubernetes-master-02 kubernetes-master-03 ;do
scp /etc/kubernetes/cfg/{kube-proxy-config.yml,kube-proxy.conf} root@${ip}:/etc/kubernetes/cfg/
scp /usr/lib/systemd/system/kube-proxy.service root@${ip}:/usr/lib/systemd/system/
done
6.11.5.8.4.1、 修改 kubernetes-master-02 配置文件
sed -i 's#172.16.0.50#172.16.0.51#g' /etc/kubernetes/cfg/kube-proxy-config.yml
sed -i 's#master-01#master-02#g' /etc/kubernetes/cfg/kube-proxy-config.yml
6.11.5.8.4.2、 修改 kubernetes-master-03 配置文件
sed -i 's#172.16.0.50#172.16.0.52#g' /etc/kubernetes/cfg/kube-proxy-config.yml
sed -i 's#master-01#master-03#g' /etc/kubernetes/cfg/kube-proxy-config.yml
6.11.5.8.4.3、 查看配置文件
for ip in kubernetes-master-01 kubernetes-master-02 kubernetes-master-03 ;do
echo ''; echo $ip; echo '';
ssh root@$ip "cat /etc/kubernetes/cfg/kube-proxy-config.yml";
done
6.11.5.8.5、 启动
systemctl daemon-reload && systemctl enable --now kube-proxy && systemctl status kube-proxy
6.11.5.8.6、 查看 kubelet 加入集群请求
[root@kubernetes-master-01 k8s]
NAME AGE SIGNERNAME
REQUESTOR CONDITION
node-csr-51i8zZdDrIFh_zGjblcnJHVTVEZF03-MRLmxqW7ubuk 50m
kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Pending
node-csr-9DyYdqmYto4MW7IcGbTPqVePH9PHQN1nNefZEFcab7s 50m
kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Pending
node-csr-YzbkiJCgLrXM2whs0h00TDceGaBI3Ntly8Z7HGCYvFw 62m
kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Pending
6.11.5.8.7、 批准加入
kubectl certificate approve `kubectl get csr | grep "Pending" | awk '{print $1}'`
6.11.5.8.8、 查看加入集群的新节点
[root@kubernetes-master-01 ~]
NAME STATUS ROLES AGE VERSION
kubernetes-master-01 Ready <none> 123m v1.18.8
kubernetes-master-02 Ready <none> 120m v1.18.8
kubernetes-master-03 Ready <none> 118m v1.18.8
kubernetes-node-01 Ready <none> 3s v1.18.8
6.11.5.8.9、 设置集群角色
[root@kubernetes-master-01 ~]
[root@kubernetes-master-01 ~]
[root@kubernetes-master-01 ~]
node/kubernetes-node-01 labeled
[root@kubernetes-master-01 ~]
NAME STATUS ROLES AGE VERSION
kubernetes-master-01 Ready master 135m v1.18.8
kubernetes-master-02 Ready master 131m v1.18.8
kubernetes-master-03 Ready master 130m v1.18.8
6.11.5.8.10、 为 master 节点打污点
master 节点一般情况下不运行 pod,因此我们需要给 master 节点添加污点使其不被调度
[root@kubernetes-master-01 ~]
node/kubernetes-master-01 modified
[root@kubernetes-master-01 ~]
node/kubernetes-master-02 modified
[root@kubernetes-master-01 ~]
node/kubernetes-master-03 modified
6.11.5.8.11、 部署集群网络插件
kubernetes 设计了网络模型,但却将它的实现交给了网络插件,CNI 网络插件最主要的功能就是实现 POD 资
源能够跨主机进行通讯。常见的 CNI 网络插件:
1. Flannel
2. Calico
3. Canal
4. Contiv
5. OpenContrail
6. NSX-T
7. Kube-router
6.11.5.8.11.1、 安装网络插件
[root@kubernetes-master-01 ~]
flanneld 100% 34MB 93.6MB/s 00:00
mk-docker-opts.sh 100% 2139 19.4MB/s 00:00
flanneld 100% 34MB 103.3MB/s 00:00
mk-docker-opts.sh 100% 2139 8.5MB/s 00:00
flanneld 100% 34MB 106.5MB/s 00:00
mk-docker-opts.sh 100% 2139
6.11.5.8.11.2、 将 flanneld 配置写入集群数据库
etcdctl \
--ca-file=/etc/etcd/ssl/ca.pem \
--cert-file=/etc/etcd/ssl/etcd.pem \
--key-file=/etc/etcd/ssl/etcd-key.pem \
--endpoints="https://192.168.1.50:2379,https://192.168.1.51:2379,https://192.168.1.52:2379" \
mk /coreos.com/network/config '{"Network":"10.244.0.0/12", "SubnetLen": 21, "Backend": {"Type": "vxlan", "DirectRouting":true}}'
[root@kubernetes-master-01 ~]
--ca-file=/etc/etcd/ssl/ca.pem \
--cert-file=/etc/etcd/ssl/etcd.pem \
--key-file=/etc/etcd/ssl/etcd-key.pem \
--endpoints="https://192.168.1.50:2379,https://192.168.1.51:2379,https://192.168.1.52:2379" \
get /coreos.com/network/config
{"Network":"10.244.0.0/12", "SubnetLen": 21, "Backend": {"Type": "vxlan","DirectRouting": true}}
6.11.5.8.11.3、 注册 Flanneld 服务
cat > /usr/lib/systemd/system/flanneld.service << EOF
[Unit]
Description=Flanneld address
After=network.target
After=network-online.target
Wants=network-online.target
After=etcd.service
Before=docker.service
[Service]
Type=notify
ExecStart=/usr/local/bin/flanneld \
-etcd-cafile=/etc/etcd/ssl/ca.pem \
-etcd-certfile=/etc/etcd/ssl/etcd.pem \
-etcd-keyfile=/etc/etcd/ssl/etcd-key.pem \
-etcd-endpoints="https://192.168.1.50:2379,https://192.168.1.51:2379,https://192.168.1.52:2379" \
-etcd-prefix=/coreos.com/network \
-ip-masq
ExecStartPost=/usr/local/bin/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/subnet.env
Restart=always
RestartSec=5
StartLimitInterval=0
[Install]
WantedBy=multi-user.target
RequiredBy=docker.service
EOF
6.11.5.8.11.3.1、 配置详解
| 配置选项 |
选项说明 |
| -etcd-cafile |
用于 etcd 通信的 SSL CA 文件 |
| -etcd-certfile |
用于 etcd 通信的的 SSL 证书文件 |
| -etcd-keyfile |
用于 etcd 通信的 SSL 密钥文件 |
| --etcd-endpoints |
所有 etcd 的 endpoints |
| -etcd-prefix |
etcd 中存储的前缀 |
| -ip-masq |
-ip-masq=true 如果设置为 true,这个参数的目的是让 flannel 进行 ip 伪装,而不让 docker 进行 ip 伪装。这么做的原因是如果 docker 进行 ip 伪装,流量再从 flannel 出去,其他 host 上看到的 source ip 就是 flannel 的网关 ip,而不是 docker 容器的 ip |
6.11.5.8.11.4、 分发配置文件
[root@kubernetes-master-01 ~]
flanneld.service 100% 697 2.4MB/s 00:00
flanneld.service 100% 697 1.5MB/s 00:00
flanneld.service 100% 697 3.4MB/s 00:00
flanneld.service 100% 697 2.6MB/s 00:00
6.11.5.8.11.5、 修改 docker 启动模式
此举是将 docker 的网络交给 flanneld 来管理,形成集群统一管理的网络。
[root@kubernetes-master-01 ~]
[root@kubernetes-master-01 ~]
[root@kubernetes-master-01 ~]
6.11.5.8.11.6、 分发 docker 启动脚本
[root@kubernetes-master-01 ~]
docker.service 100% 1830 6.0MB/s 00:00
docker.service 100% 1830 4.7MB/s 00:00
docker.service 100% 1830 6.6MB/s 00:00
docker.service 100% 1830
6.11.5.8.11.7、 启动 Flanneld 服务
[root@kubernetes-master-01 ~]
kubernetes-master-01
kubernetes-master-02
kubernetes-master-03
kubernetes-node-01
kubernetes-node-02
6.11.5.8.12、 部署 CoreDNS
CoreDNS 用于集群中 Pod 解析 Service 的名字,Kubernetes 基于 CoreDNS 用于服务发现功能
6.11.5.8.12.1、 下载配置文件
git clone https://github.com/coredns/deployment.git
6.11.5.8.12.2、 绑定集群匿名用户权限
[root@kubernetes-master-01 ~]
clusterrolebinding.rbac.authorization.k8s.io/cluster-system-anonymous created
6.11.5.8.12.3、 修改 CoreDNS 并运行
[root@kubernetes-master-01 ~]
[root@kubernetes-master-01 ~]
serviceaccount/coredns unchanged
clusterrole.rbac.authorization.k8s.io/system:coredns unchanged
clusterrolebinding.rbac.authorization.k8s.io/system:coredns unchanged
configmap/coredns unchanged
deployment.apps/coredns unchanged
service/kube-dns created
[root@kubernetes-master-01 ~]
NAME READY STATUS RESTARTS AGE
coredns-85b4878f78-5xr2z 1/1 Running 0 2m31s
6.11.5.8.13、 绑定用户的超管权限
[root@kubernetes-master-01 ~]
clusterrolebinding.rbac.authorization.k8s.io/cluster-system-anonymous created
6.11.5.8.14、 测试集群 DNS
[root@kubernetes-master-01 ~]
If you don't see a command prompt, try pressing enter.
/ # nslookup docs.docs.svc.cluster.local
Server: 10.96.0.2
Address 1: 10.96.0.2 kube-dns.kube-system.svc.cluster.local
Name: docs.docs.svc.cluster.local
Address 1: 10.241.96.2 10-241-96-2.docs.docs.svc.cluster.local
Address 2: 10.242.0.2 10-242-0-2.docs.docs.svc.cluster.local
6.12、部署集群 Node 节点
Node 节点主要负责提供应用运行环境,其最主要的组件就是 kube-proxy 和 kubelet。接下来我们就在集群当中部署 Node 节点。
6.12.1、 分发工具
[root@kubernetes-master-01 bin]
kubelet 100% 108MB 120.2MB/s 00:00
kube-proxy 100% 37MB 98.1MB/s 00:00
kubelet 100% 108MB 117.4MB/s 00:00
for i in kubernetes-node-02 kubernetes-node-01; do echo $i; ssh root@$i "ls -lh
/usr/local/bin"; done
6.12.2、 颁发 Node 节点证书
cd /etc/kubernetes/ssl
for i in kubernetes-node-01 kubernetes-node-02; do ssh root@$i "mkdir -pv /etc/kubernetes/ssl" && scp -pr ./{ca*.pem,admin*pem,kube-proxy*pem} root@$i:/etc/kubernetes/ssl;done
6.12.3、 配置 TLS bootstrapping
TLS bootstrapping 是用来简化管理员配置 kubelet 与 apiserver 双向加密通信的配置步骤的一种机制。当集群开启了 TLS 认证后,每个节点的 kubelet 组件都要使用由 apiserver 使用的 CA 签发的有效证书才能与apiserver 通讯,此时如果有很多个节点都需要单独签署证书那将变得非常繁琐且极易出错,导致集群不稳。TLS bootstrapping 功能就是让 node 节点上的 kubelet 组件先使用一个预定的低权限用户连接到 apiserver,然后向 apiserver 申请证书,由 apiserver 动态签署颁发到 Node 节点,实现证书签署自动化。
6.12.4、 生成 TLS bootstrapping 所需 token
TLS_BOOTSTRAPPING_TOKEN=`head -c 16 /dev/urandom | od -An -t x | tr -d ' '`
cat > token.csv << EOF
${TLS_BOOTSTRAPPING_TOKEN},kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF
[root@kubernetes-master-01 k8s]
[root@kubernetes-master-01 k8s]
[root@kubernetes-master-01 k8s]
${TLS_BOOTSTRAPPING_TOKEN},kubelet-bootstrap,10001,"system:kubelet-bootstrap"
EOF
[root@kubernetes-master-01 k8s]
1b076dcc88e04d64c3a9e7d7a1586fe5,kubelet-bootstrap,10001,"system:kubelet-bootstrap"
6.12.5、 创建 TLS Bootstrapping 集群配置文件
在 kubernetes 中,我们需要创建一个配置文件,用来配置集群、用户、命名空间及身份认证等信息。
export KUBE_APISERVER="https://172.16.0.55:8443"
kubectl config set-cluster kubernetes \
--certificate-authority=/etc/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=kubelet-bootstrap.kubeconfig
kubectl config set-credentials "kubelet-bootstrap" \
--token=3ac791ff0afab20f5324ff898bb1570e \
--kubeconfig=kubelet-bootstrap.kubeconfig
kubectl config set-context default \
--cluster=kubernetes \
--user="kubelet-bootstrap" \
--kubeconfig=kubelet-bootstrap.kubeconfig
kubectl config use-context default --kubeconfig=kubelet-bootstrap.kubeconfig
6.12.6、 分发 TLS bootstrap 证书
for i in kubernetes-node-01 kubernetes-node-02;do ssh root@$i "mkdir -p /etc/kubernetes/cfg" && scp token.csv kube-scheduler.kubeconfig kube-controller-manager.kubeconfig admin.kubeconfig kube-proxy.kubeconfig kubelet-bootstrap.kubeconfig root@$i:/etc/kubernetes/cfg;done
6.12.7、 配置 kubelet 服务
for ip in kubernetes-node-01 kubernetes-node-02;do ssh root@${ip} "mkdir -pv /var/log/kubernetes" && ssh root@${ip} "mkdir -pv /etc/kubernetes/cfg/" && scp /etc/kubernetes/cfg/{kubelet-config.yml,kubelet.conf} root@${ip}:/etc/kubernetes/cfg && scp /usr/lib/systemd/system/kubelet.service root@${ip}:/usr/lib/systemd/system;done
6.12.8、 处理配置文件
sed -i 's#master-01#node-01#g' /etc/kubernetes/cfg/kubelet.conf
sed -i 's#172.16.0.50#172.16.0.53#g' /etc/kubernetes/cfg/kubelet-config.yml
sed -i 's#master-01#node-02#g' /etc/kubernetes/cfg/kubelet.conf
sed -i 's#172.16.0.50#172.16.0.54#g' /etc/kubernetes/cfg/kubelet-config.yml
6.12.9、 开启 kubelet
systemctl daemon-reload;systemctl enable --now kubelet;systemctl status kubelet.service
6.12.10、 配置 kube-proxy 服务
for ip in kubernetes-node-01 kubernetes-node-02;do scp /etc/kubernetes/cfg/{kube-proxy-config.yml,kube-proxy.conf} root@${ip}:/etc/kubernetes/cfg/ && scp /usr/lib/systemd/system/kube-proxy.service root@${ip}:/usr/lib/systemd/system/;done
6.12.11、 修改配置文件
sed -i 's#172.16.0.50#172.16.0.54#g' /etc/kubernetes/cfg/kube-proxy-config.yml
sed -i 's#master-01#node-02#g' /etc/kubernetes/cfg/kube-proxy-config.yml
sed -i 's#172.16.0.50#172.16.0.54#g' /etc/kubernetes/cfg/kube-proxy-config.yml
sed -i 's#master-01#node-02#g' /etc/kubernetes/cfg/kube-proxy-config.yml
6.12.12、 设置开机自启动
systemctl daemon-reload; systemctl enable --now kube-proxy; systemctl status kube-proxy
6.12.13、 分发网络插件
for i in kubernetes-node-01 kubernetes-node-02; do scp flanneld mk-docker-opts.sh root@$i:/usr/local/bin; done
6.12.14、 同步 ETCD 配置至节点
for i in kubernetes-node-01 kubernetes-node-02;do ssh root@$i "mkdir -pv /etc/etcd/ssl" && scp -p /etc/etcd/ssl/*.pem root@$i:/etc/etcd/ssl;done
6.12.15、 分发 flannel
for i in kubernetes-node-01 kubernetes-node-02;do scp /usr/lib/systemd/system/flanneld.service root@$i:/usr/lib/systemd/system; done
6.12.16、 分发 Docker 脚本
[root@kubernetes-master-01 ~]
docker.service 100% 1830 6.0MB/s 00:00
docker.service 100% 1830
6.12.17、 重启 docker,开启 flanneld 服务
[root@kubernetes-master-01 ~]
>>> kubernetes-master-01
>>> kubernetes-master-02
>>> kubernetes-master-03
>>> kubernetes-node-01
>>> kubernetes-node-02
6.12.18、 查看 kubelet 加入集群请求
[root@kubernetes-master-01 k8s]
NAME AGE SIGNERNAME
REQUESTOR CONDITION
node-csr-51i8zZdDrIFh_zGjblcnJHVTVEZF03-MRLmxqW7ubuk 50m
kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Pending
node-csr-9DyYdqmYto4MW7IcGbTPqVePH9PHQN1nNefZEFcab7s 50m
kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Pending
node-csr-YzbkiJCgLrXM2whs0h00TDceGaBI3Ntly8Z7HGCYvFw 62m
kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Pending
6.12.19、 批准加入
kubectl certificate approve `kubectl get csr | grep "Pending" | awk '{print $1}'`
kubectl label nodes kubernetes-node-01 node-role.kubernetes.io/node=kubernetes-node-01
kubectl label nodes kubernetes-node-02 node-role.kubernetes.io/node=kubernetes-node-02
6.12.20、 查看节点
[root@kubernetes-master-01 k8s]
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP
OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
kubernetes-master-01 Ready master 10d v1.18.8 192.168.12.71 <none>
CentOS Linux 7 (Core) 4.4.233-1.el7.elrepo.x86_64 docker://19.3.13
kubernetes-master-02 Read[root@kubernetes-master-01 ~]
deployment.apps/nginx created
[root@kubernetes-master-01 ~]
--type=NodePort
service/nginx exposedy master 10d v1.18.8 192.168.12.72 <none>
CentOS Linux 7 (Core) 4.4.233-1.el7.elrepo.x86_64 docker://19.3.13
kubernetes-master-03 Ready master 10d v1.18.8 192.168.12.73 <none>
CentOS Linux 7 (Core) 4.4.233-1.el7.elrepo.x86_64 docker://19.3.13
kubernetes-node-01 Ready node 10d v1.18.8 192.168.12.74 <none>
CentOS Linux 7 (Core) 4.4.233-1.el7.elrepo.x86_64 docker://19.3.13
kubernetes-node-02 Ready node 10d v1.18.8 192.168.12.75 <none>
CentOS Linux 7 (Core) 4.4.233-1.el7.elrepo.x86_64 docker://19.3.13
6.12.21、 验证集群
[root@kubernetes-master-01 ~]
deployment.apps/nginx created
[root@kubernetes-master-01 ~]
service/nginx exposed
三、 部署 Dashboard
Dashboard 是基于网页的 Kubernetes 用户界面。您可以使用 Dashboard 将容器应用部署到 Kubernetes 集群中,也可以对容器应用排错,还能管理集群本身及其附属资源。您可以使用 Dashboard 获取运行在集群中的应用的概览信息,也可以创建或者修改 Kubernetes 资源(如 Deployment,Job,DaemonSet 等等)。例如,您
可以对 Deployment 实现弹性伸缩、发起滚动升级、重启 Pod 或者使用向导创建新的应用
1、 下载资源清单
[root@localhost ~]
--2020-09-15 12:05:15--
https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.4/aio/deploy/recomme
nded.yaml
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.8.133
Connecting to raw.githubusercontent.com
(raw.githubusercontent.com)|151.101.8.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 7552 (7.4K) [text/plain]
Saving to: ‘recommended.yaml’
100%[===========================================================================
================================================================================
========================================>] 7,552 --.-K/s in 0s
2020-09-15 12:05:17 (29.3 MB/s) - ‘recommended.yaml’ saved [7552/7552]
[root@localhost ~]
image: kubernetesui/dashboard:v2.0.4
imagePullPolicy: Always
image: kubernetesui/metrics-scraper:v1.0.4
[root@localhost ~]
[root@localhost ~]
[root@localhost ~]
image: registry.cn-hangzhou.aliyuncs.com/k8sos/dashboard:v2.0.4
imagePullPolicy: Always
image: registry.cn-hangzhou.aliyuncs.com/k8sos/metrics-scraper:v1.0.4
2、 修改 Service kubernetes-dash
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
ports:
- port: 443
targetPort: 8443
selector:
k8s-app: kubernetes-dashboard
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
ports:
- port: 443
targetPort: 8443
nodePort: 30001
selector:
k8s-app: kubernetes-dashboard
type: NodePort
3、 部署 Dashboard
[root@localhost ~]
namespace/kubernetes-dashboard create
serviceaccount/kubernetes-dashboard created
service/kubernetes-dashboard created
secret/kubernetes-dashboard-certs created
secret/kubernetes-dashboard-csrf created
secret/kubernetes-dashboard-key-holder created
configmap/kubernetes-dashboard-settings created
role.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
deployment.apps/kubernetes-dashboard created
service/dashboard-metrics-scraper created
deployment.apps/dashboard-metrics-scraper created
[root@localhost ~]
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 7m5s
[root@localhost ~]
NAME READY STATUS RESTARTS AGE
dashboard-metrics-scraper-79694cfc8b-cxr8x 1/1 Running 0 18s
kubernetes-dashboard-57bd6cb5d6-fgxnf 1/1 Running 0 18s
4、 查看部署状态以及部署资源
[root@localhost ~]
NAME STATUS AGE
namespace/kubernetes-dashboard Active 107s
NAME SECRETS AGE
serviceaccount/kubernetes-dashboard 1 107s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes-dashboard NodePort 10.96.138.93 <none> 443:30001/TCP 41s
NAME TYPE DATA AGE
secret/kubernetes-dashboard-certs Opaque 0 107s
secret/kubernetes-dashboard-csrf Opaque 1 107s
secret/kubernetes-dashboard-key-holder Opaque 2 107s
NAME DATA AGE
configmap/kubernetes-dashboard-settings 0 107s
NAME CREATED AT
role.rbac.authorization.k8s.io/kubernetes-dashboard 2021-06-15T08:32:11Z
NAME CREATED AT
clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard 2021-06-15T08:32:11Z
NAME ROLE AGE
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard Role/kubernetes-dashboard 107s
NAME ROLE AGE
clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard ClusterRole/kubernetes-dashboard 107s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/kubernetes-dashboard 1/1 1 1 107s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/dashboard-metrics-scraper ClusterIP 10.96.39.145 <none> 8000/TCP 107s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/dashboard-metrics-scraper 1/1 1 1 107s
5、 部署 Token
[root@localhost ~]
[root@localhost ~]
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kube-system
[root@localhost ~]
serviceaccount/admin-user created
clusterrolebinding.rbac.authorization.k8s.io/admin-user created
[root@localhost ~]
Name: admin-user-token-b6kp7
Namespace: kube-system
Labels: <none>
Annotations: kubernetes.io/service-account.name: admin-user
kubernetes.io/service-account.uid:
43d73e50-b17b-4bd3-a502-d1678364fad5
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1066 bytes
namespace: 11 bytes
token:
eyJhbGciOiJSUzI1NiIsImtpZCI6ImZxdTVycGZJUDdmclFKRXFFSXB0enEzbzBUT1VGaWx3aEMzWGdH
S3ZOVEUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZ
XJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZ
WFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLWI2a3A3Iiwia3ViZXJuZXRlcy5pb
y9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ld
GVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI0M2Q3M2U1MC1iMTdiLTRiZ
DMtYTUwMi1kMTY3ODM2NGZhZDUiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0Z
W06YWRtaW4tdXNlciJ9.H8xSQR6a8wrBDcCk-hHDfEuJwsupGmWNMMPd_2sNbIRr2-TH0IwoCPmZsqSw
4TJcOQwNFY6rW3w5J0UJiPT0JfNbQ2g2QccRXil8i1xCws9X-JvZaTQ9hv4zFOQjeYLkO7AYrLokmbGW
3wM2wf0EhoK6PkLrW-JwxNQdcq_x1cJ_ZuHGmIP-MkGI7q3xel1NJgF_D57krANTcPfimUCqHmnqP6OH
FlDDaeGC83WwCAMyW2-WH-LRK1UEOEg8HrCH8KE5XRraEHeOBAThoNfemhRbqJMMHOIL2l_P0w62hpG0
5D01N9lgIEQCc8eQJHylrPurk37ULPE8zOPiV4oadg
四、 Kubernetes 基础
1、 kubernetes 基础使用篇
1.1、 kubernetes 带来的变革
1.1.1、对于开发人员
由于公司业务多,开发环境、测试环境、预生产环境和生产环境都是隔离的,而且除了生产环境,为了节省成本,其他环境可能是没有日志收集的,在没有用 k8s 的时候,查看线下测试的日志,需要开发或者测试人员,找到对应的机器,在找到对应的容器,然后才能查看日志,在用了 k8s 之后,开发和测试可以直接在 k8s的dashboard 到对应的 namespace,即可定位到业务的容器,然后可以直接通过控制台查看到对应的日志,大大降低了操作时间。把应用部署到 k8s 之后,代码的发布、回滚,以及蓝绿发布、金丝雀发布等都变得特别简单,不仅加快了业务代码迭代的速度,而且全程无需人工干预。目前我们使用 jenkins、gitrunner 进行发版或者回滚等,从开发环境到测试环境,到生产环境,完全遵守一次构建,多集群、多环境部署,通过不同的启动参数、不同的环境变量、不同的配置文件实现区分不同的环境。目前已经实现 Python、Java、PHP、NodeJS、Go、.NET Core、Python 等多种语言的一键式发版、一键式回滚,大大提高了开发人员的开发效率。在使用服务网格后,开发人员在开发应用的过程中,不用再关心代码的网络部分,这些功能都被服务网格实现,让开发人员可以只关心代码逻辑部分,即可实现网络部分的功能,比如:断流、分流、路由、负载均衡、限速和触发故障等功能。测试过程中,可能同时多套环境,当然也会需要再创建一套测试环境,之前测试环境的创建,需要找运维或者自行手工搭建。在迁移至 k8s 集群后,只需要在 jenkins 上点点鼠标即可在 k8s 集群上创建一套新的测试环境。
1.1.2、对于运维人员
如果你是一名运维人员,可能经常因为一些重复、繁琐的工作感觉厌倦。比如:这个需要一套新的测试环境,那个需要一套新的测试环境,之前可能需要装系统、装依赖环境、开通权限等等。而如今,可以直接用镜像直接部署一套新的测试环境,甚至全程无需自己干预,开发人员通过 jenkins 或者自动化运维平台即可一键式创建,
大大降低了运维成本。一开始,公司业务故障,可能是因为基础环境不一致、依赖不一致、端口冲突等等问题,现在实现 Docker镜像部署,k8s 编排,所有的依赖、基础都是一样的,并且环境的自动化扩容、健康检查、容灾、恢复都是全自动的,大大减少了因为这类基础问题引发的故障。也有可能公司业务是由于服务器宕机、网络等问题,造成服务
不可用,此类情况均需要运维人员及时去修复,而如今,可能在你收到告警信息的时候,k8s 已经帮你恢复了。在没有使用 k8s 时,业务应用的扩容和缩容,都需要人工去处理,从采购服务器、上架、到部署依赖环境,不仅需要大量的人力物力,而且非常容易在中间过程出现问题,又要花费大量的时间去查找问题。成功上架后,还需要在前端反代端添加或该服务器,而如今,可以利用 k8s 的弹性计算,一键式进行扩容和缩容,不仅大大提高了运维效率,而且还节省了不少的服务器资源,提高了资源利用率。对于反代配置方面,比如可能你并不会,或者对 nginx 的配置规则并不熟悉,一些高级的功能你也不会实现,而如今,利用 k8s 的 ingress 即可简单的实现那些复杂的逻辑。并且也不会在遇到 nginx 少加一个斜杠和多加一个斜杠的问题。对于负载均衡方面,之前负载均衡可能是 Nginx、LVS、HAProxy、F5 等,云上可能是云服务商提供的不在均衡机制。每次添加删除节点时,都需要手动去配置前端负载均衡,手动去匹配后端节点,而如今,使用 k8s 内部的 service 可以动态发现实现自动管理节点,并且支持自动扩容缩容。之前遇到高峰流量时,经常服务器性能不够,需要临时加服务器面对高峰流量,而如今对于高性能 k8s 集群加上 serverless,基本实现无需管理,自动扩容。
对于高可用方面,k8s 天生的高可用功能,彻底释放了双手,无需再去创建各类高可用工具、检测检查脚本。k8s 支持进程接口级别的健康检查,如发现接口超时或者返回值不正确,会自动处理该问题。对于中间件搭建方面,根据定义好的资源文件,可以实现秒级搭建各类中间件高可用集群,并且支持一键式扩缩容,如 Redis、RabbitMQ、Zookeeper 等,并且大大减少了出错的概率。对于应用端口方面,传统行业中,一个服务器可能跑了很多进程,每个进程都有一个端口,需要人为的去配置端口,并且还需要考虑端口冲突的问题,如果有防火墙的话,还需要配置防火墙,在 k8s 中,端口统一管理,统一配置,每个应用的端口都可设置成一样的,之后通过 service 进行负载均衡,大大降低了端口管理的复杂度和端口冲突。无论是对于开发人员、测试人员还是运维人员,k8s 的诞生,不仅减少了工作的复杂性,还减少了各种成本。上述带来的变革只是其中比较小的一部分,更多优点只有用了才能体会到。
1.3、 POD
K8s 有很多技术概念,同时对应很多 API 对象,最重要的也是最基础的是微服务 Pod。Pod 是在 K8s 集群中运行部署应用或服务的最小单元,它是可以支持多容器的。Pod 的设计理念是支持多个容器在一个 Pod 中共享网络地址和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。Pod 对多容器的支持是 K8s
最基础的设计理念。比如你运行一个操作系统发行版的软件仓库,一个 Nginx 容器用来发布软件,另一个容器专门用来从源仓库做同步,这两个容器的镜像不太可能是一个团队开发的,但是他们一块儿工作才能提供一个微服务;这种情况下,不同的团队各自开发构建自己的容器镜像,在部署的时候组合成一个微服务对外提供服务。这就是 K8S 中的 POD。
Pod 是 K8s 集群中所有业务类型的基础,可以看作运行在 K8s 集群中的小机器人,不同类型的业务就需要不同类型的小机器人去执行。目前 K8s 中的业务主要可以分为长期伺服型(long-running)、批处理型(batch)、节点后台支撑型(node-daemon)和有状态应用型(stateful application);分别对应的小机器人控制器为Deployment、Job、DaemonSet 和 StatefulSet。
1.3.1、Pod 的初体验
apiVersion: v1
kind: Pod
metadata:
name: first-pod
labels:
app: bash
spec:
containers:
- name: bash-container
image: busybox
command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 10']
1.3.1.1、 执行结果
[root@instance-gvpb80ao docs]
pod/first-pod created
[root@instance-gvpb80ao docs]
NAME READY STATUS RESTARTS AGE
first-pod 0/1 ContainerCreating 0 6
1.3.2、Pod 带来的好处
1. Pod 做为一个可以独立运行的服务单元,简化了应用部署的难度,以更高的抽象层次为应用部署管提供了极大的方便。
2. Pod 做为最小的应用实例可以独立运行,因此可以方便的进行部署、水平扩展和收缩、方便进行调度管理与资源的分配。
3. Pod 中的容器共享相同的数据和网络地址空间,Pod 之间也进行了统一的资源管理与分配。
1.3.3、Pod 是如何管理多个容器的
Pod 中可以同时运行多个进程(作为容器运行)协同工作。同一个 Pod 中的容器会自动的分配到同一个 node上。同一个 Pod 中的容器共享资源、网络环境和依赖,所以它们总是被同时调度。在一个 Pod 中同时运行多个容器是一种比较高级的用法。只有当你的容器需要紧密配合协作的时候才考虑用这种模式。
1.3.4、Pod 中的数据持久性
Pod 在设计⽀持就不是作为持久化实体的。在调度失败、节点故障、缺少资源或者节点维护的状态下都会死掉会被驱逐。通常,我们是需要借助类似于 Docker 存储卷这样的资源来做 Pod 的数据持久化的。
1.3.5、Pod 的生命周期和重启策略
Pod 在整个生命周期过程中被系统定义为各种状态,熟悉 Pod 各种状态对于理解如何设置 Pod 的调度策略、重启策略是很有必要的。
1.3.5.1、 Pod 的状态
| 状态值 |
描述 |
| 挂起(Pending) |
API Server 创建了 pod 资源对象已存入 etcd 中,但它尚未被调度完成,或者仍处于从仓库下载镜像的过程中。 |
| 运行中(Running) |
Pod 已经被调度至某节点,并且所有容器都已经被 kubelet 创建完成 |
| 成功(Succeeded) |
Pod 中的所有容器都已经成功终止并且不会被重启 |
| 失败(Failed) |
Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。即容器以非 0 状态退出或者被系统禁止。 |
| 未知(Unknown) |
Api Server 无法正常获取到 Pod 对象的状态信息,通常是由于无法与所在工作节点的 kubelet 通信所致。 |
1.3.5.2、 Pod 的重启策略
Pod 重启策略( RestartPolicy )应用于 Pod 内的所有容器,井且仅在 Pod 所处的 Node 上由 kubelet 进行判断和重启操作。当某个容器异常退出或者健康检查失败时, kubelet 将根据 RestartPolicy 设置来进行相应的操作。Pod 的重启策略包括:Always、OnFailure 和 Never,默认值为 Always
1. Always:当容器失效时,由 kubelet 自动重启该容器。
2. OnFailure:当容器终止运行且退出码不为 0 时,由 kubelet 自动重启该容器
3. Never:不论容器运行状态如何,kubelet 都不会重启该容器。
kubelet 重启失效容器的时间间隔以 sync-frequency 乘以 2n 来计算;例如 1、2、4、8 倍等,最长延时 5min ,并且在成功重启后的 10 min 后重置该时间。Pod 的重启策略与控制方式息息相关,当前可用于管理 Pod 的控制器包括 ReplicationController、Job、DaemonSet 及直接通过 kubelet 管理(静态 Pod)。每种控制器对 Pod 的重启策略要求如下:
1.RC 和 DaemonSet:必须设置为 Always,需要保证该容器持续运行。
2.Job 和 CronJob:OnFailure 或 Never,确保容器执行完成后不再重启。
3.kubelet:在 Pod 失效时自动重启它,不论将 RestartPolicy 设置为什么值,也不会对 Pod 进行健康检查。
1.3.6、Pod 的资源清单详解
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: web-testing
labels:
- app: nginx
annotations:
- app: nginx
spec:
containers:
- name: nginx
image: nginx:v1
imagePullPolicy: Always
workingDir: /usr/share/nginx/html
volumeMounts:
- name: webroot
mountPath: /usr/share/nginx/html
readOnly: true
ports:
- name: http
containerPort: 80
protocol: TCP
env:
- name: TZ
value: Asia/Shanghai
- name: LANG
value: en_US.utf8
resources:
limits:
cpu: 1000m
memory: 1024MiB
requests:
cpu: 100m
memory: 512MiB
readinessProbe:
httpGet:
path: /
port: 80
timeoutSeconds: 2
initialDelaySeconds: 60
livenessProbe:
exec:
command:
- cat
- /health
httpGet:
path: /_health
port: 8080
httpHeaders:
- name: end-user
value: jason
tcpSocket:
port: 80
initialDelaySeconds: 60
timeoutSeconds: 2
periodSeconds: 5
successThreshold: 2
failureThreshold: 1
securityContext:
provoleged: false
restartPolicy: Always
nodeSelector:
region: subnet7
imagePullSecrets:
- name: default-dockercfg-86258
hostNetwork: false
volumes:
- name: webroot
emptyDir: {}
hostPath:
path: /etc/hosts
secret:
secretName: default-token-tf2jp
defaultMode: 420
configMap:
name: nginx-conf
defaultMode: 420
1.4、 Label
Label 是 Kubernetes 系统中另外一个核心概念。一个 Label 是一个 key=value 的键值对,其中 key 与 vaue 由用户自己指定。Label 可以附加到各种资源对象上,例如 Node、Pod、Service、RC 等,一个资源对象可以定义任意数量的 Label,同一个 Label 也可以被添加到任意数量的资源对象上去,Label 通常在资源对象定义时确定,也可以在对象创建后动态添加或者删除。我们可以通过指定的资源对象捆绑一个或多个不同的 Label 来实现多维度的资源分组管理功能,以便于灵活、方便地进行资源分配、调度、配置、部署等管理工作。例如:部署不同版本的应用到不同的环境中;或者监控和分析应用(日志记录、监控、告警)等。一些常用等 label 示例如下。
版本标签:"release" : "stable" , "release" : "canary"
环境标签:"environment" : "dev" , "environment" : "production"
架构标签:"tier" : "frontend" , "tier" : "backend" , "tier" : "middleware"
分区标签:"partition" : "customerA" , "partition" : "customerB"
质量管控标签:"track" : "daily" , "track" : "weekly"
Label 相当于我们熟悉的“标签”,給某个资源对象定义一个 Label,就相当于給它打了一个标签,随后可以通过 Label Selector(标签选择器)查询和筛选拥有某些 Label 的资源对象,Kubernetes 通过这种方式实现了类似SQL 的简单又通用的对象查询机制。
1.4.1、根据标签来查询 Pod
[root@kubernetes-master-01 ~]
NAME READY STATUS RESTARTS AGE LABELS
docs-85686dc954-6jv56 1/1 Running 1 10d app=docs,pod-template-hash=85686dc954
docs-85686dc954-hr427 1/1 Running 0 10d app=docs,pod-template-hash=85686dc954
1.4.2、增加标签
[root@kubernetes-master-01 ~]
pod/docs-85686dc954-6jv56 labeled
[root@kubernetes-master-01 ~]
NAME READY STATUS RESTARTS AGE LABELS
docs-85686dc954-6jv56 1/1 Running 1 10d app=docs,dev=test,pod-template-hash=85686dc954
docs-85686dc954-hr427 1/1 Running 0 10d app=docs,pod-template-hash=85686dc954
1.4.3、删除标签
[root@kubernetes-master-01 ~]
[root@kubernetes-master-01 ~]
NAME READY STATUS RESTARTS AGE LABELS
docs-85686dc954-6jv56 1/1 Running 1 10d app=docs,pod-template-hash=85686dc954
docs-85686dc954-hr427 1/1 Running 0 10d app=docs,pod-template-hash=85686dc954
1.4.4、可以将标签显示为列
[root@kubernetes-master-01 ~]
NAME READY STATUS RESTARTS AGE APP
docs-85686dc954-6jv56 1/1 Running 1 10d docs
docs-85686dc954-hr427 1/1 Running 0 10d docs
1.5、 service 资源
service 是 k8s 中的一个重要概念,主要是提供负载均衡和服务自动发现。它是 k8s 中最核心的资源之一,每一个 Service 就是我们平常所说的一个“微服务”。在非 k8s 世界中,管理员可以通过在配置文件中指定 IP 地址或主机名,容许客户端访问,但在 k8s 中这种方式是行不通的。因为 Pod 是有生命周期的,它们可以被创建或销毁。虽然通过控制器能够动态地创建 Pod,但当 Pod 被分配到某个节点时,K8s 都会为其分配一个 IP 地址,而该 IP 地址不总是稳定可依赖的。因此,在 Kubernetes 集群中,如果一组 Pod(称为 backend)为其它 Pod (称为 frontend)提供服务,那么那些 frontend 该如何发现,并连接到这组 backend 的 Pod 呢?
如下图所示,Kubernetes 的 Service 定义了一个服务的访问入口,前端的应用(Pod)通过这个入口地址访问其背后的一组由 Pod 副本组成的集群实例,Service 与其后端的 Pod 副本集群之间是通过 Label Selector 来实现关联的,而 Deployment 则是保证 Service 的服务能力和服务质量始终处于预期的标准。通过分析,识别并建模系统中的所有服务为微服务,最终我们的系统是由多个提供不同业务能力而彼此独立的微服务单元所组成,服务之间通过 TCP/IP 进行通信,从而形成了强大而又灵活的弹性网络,拥有强大的分布式能力、弹性扩展能力、容错能力。
1.5.1、定义 Service
kind: Service
apiVersion: v1
metadata:
name: test-service
namespace: default
labels:
app: test-service
spec:
type: ClusterIP
selector:
app: test-service
ports:
- port: 80
targetPort: 80
1.5.2、Service 的工作方式
在 Kubernetes 迭代过程中,给 Service 设置里三种工作方式,分别是:Userspace 方式、Iptables 以及 Ipvs,这三种方式到现在为止,官方推荐使用 IPVS, 当集群不支持 IPVS 的时候,集群会降级到 Iptables。

1.5.2.1、 Userspace
Client Pod 要访问 Server Pod 时,它先将请求发给本机内核空间中的 service 规则,由它再将请求,转给监听在指定套接字上的 kube-proxy,kube-proxy 处理完请求,并分发请求到指定 Server Pod 后,再将请求递交给内核空间中的 service,由 service 将请求转给指定的 Server Pod。由于其需要来回在用户空间和内核空间交互通信,因此效率很差。

1.5.2.2、 Iptables 模型
直接由内核中的 iptables 规则,接受 Client Pod 的请求,并处理完成后,直接转发给指定 ServerPod。这种方式不再将请求转发给 kube-proxy,性能提升很多。

1.5.2.3、 Ipvs 模型
在 ipvs 模式下,kube-proxy 监视 Kubernetes 服务和端点,调用 netlink 接口相应地创建 IPVS 规则, 并定期将 IPVS 规则与 Kubernetes 服务和端点同步。 该控制循环可确保 IPVS 状态与所需状态匹配。 访问服务时,IPVS 将流量定向到后端 Pod 之一。IPVS 代理模式基于类似于 iptables 模式的 netfilter 挂钩函数,但是使用哈希表作为基础数据结构,并且在内核空间中工作。 这意味着,与 iptables 模式下的 kube-proxy 相比,IPVS 模式下的 kube-proxy 重定向通信的
延迟要短,并且在同步代理规则时具有更好的性能。与其他代理模式相比,IPVS 模式还支持更高的网络流量吞吐量。
以上不论哪种,kube-proxy 都通过 watch 的方式监控着 kube-APIServer 写入 etcd 中关于 Pod 的最新状态信息, 它一旦检查到一个 Pod 资源被删除了 或 新建,它将立即将这些变化,反应再 iptables 或 ipvs 规则中,以便iptables 和 ipvs 在调度 Clinet Pod 请求到 Server Pod 时,不会出现 Server Pod 不存在的情况。自 k8s1.1 以后,service 默认使用 ipvs 规则,若 ipvs 没有被激活,则降级使用 iptables 规则. 但在 1.1 以前,service使用的模式默认为 userspace。

1.5.3、Service 类型
Service 是 Kubernetes 对外访问的窗口,针对不同的场景,kubernetes 为我们设置了四种 Service 的类型。
1.5.3.1、 ClusterIP
kubernetes 默认就是这种方式,是集群内部访问的方式,外部是无法访问的。其主要用于为集群内 Pod 访问时,提供的固定访问地址,默认是自动分配地址,可使用 ClusterIP 关键字指定固定 IP。
[root@kubernetes-master-01 test]
kind: Service
apiVersion: v1
metadata:
name: my-svc
spec:
type: ClusterIP
selector:
app: nginx
ports:
- port: 80
targetPort: 80
[root@kubernetes-master-01 test]
service/my-svc created
[root@kubernetes-master-01 test]
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11d
my-svc ClusterIP 10.96.222.172 <none> 80/TCP 21s
nginx NodePort 10.96.6.147 <none> 80:42550/TCP 11m
[root@kubernetes-master-01 test]
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
1.5.3.1.1、 Headless Service
kubernates 中还有一种 service 类型:headless serivces 功能,字面意思无 service 其实就是改 service 对外无提供 IP。一般用于对外提供域名服务的时候,我们在 Ingress 章节详讲。
[root@kubernetes-master-01 test]
service/my-svc created
[root@kubernetes-master-01 test]
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11d
my-svc ClusterIP None <none> 80/TCP 4s
nginx NodePort 10.96.6.147 <none> 80:42550/TCP 30m
1.5.3.2、 NodePort
NodePort 是将主机 IP 和端口跟 kubernetes 集群所需要暴露的 IP 和端口进行关联,方便其对外提供服务。内部可以通过 ClusterIP 进行访问,外部用户可以通过 NodeIP:NodePort 的方式单独访问每个 Node 上的实例。
[root@kubernetes-master-01 test]
service/my-svc created
[root@kubernetes-master-01 test]
kind: Service
apiVersion: v1
metadata:
name: my-svc
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080
[root@kubernetes-master-01 test]
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11d
my-svc NodePort 10.96.159.234 <none> 80:30080/TCP 12s
nginx NodePort 10.96.6.147 <none> 80:42550/TCP 17m
[root@kubernetes-master-01 test]
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
1.5.3.3、 LoadBalancer
LoadBalancer 类型的 service 是可以实现集群外部访问服务的另外一种解决方案。不过并不是所有的 k8s 集群都会支持,大多是在公有云托管集群中会支持该类型。负载均衡器是异步创建的,关于被提供的负载均衡器的信息将会通过 Service 的 status.loadBalancer 字段被发布出去。
[root@kubernetes-master-01 ~]
apiVersion: v1
kind: Service
metadata:
name: loadbalancer
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
selector:
app: nginx
EOF
[root@kubernetes-node-01 ~]
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 110d
loadbalancer LoadBalancer 10.0.129.18 81.71.12.240 80:30346/TCP 11s
1.5.3.4、 ExternalName
ExternalName Service 是 Service 的一个特例,它没有选择器,也没有定义任何端口或 Endpoints。它的作用是返回集群外 Service 的外部别名。它将外部地址经过集群内部的再一次封装(实际上就是集群 DNS 服务器将 CNAME解析到了外部地址上),实现了集群内部访问即可。例如你们公司的镜像仓库,最开始是用 ip 访问,等到后面域名下来了再使用域名访问。你不可能去修改每处的引用。但是可以创建一个 ExternalName,首先指向到 ip,等后面再指向到域名。
kind: Service
apiVersion: v1
metadata:
name: my-svc
spec:
type: ExternalName
externalName: www.baidu.co
1.6、 deployment 资源
Deployment 为 Pod 提供声明式更新。在 Deployment 对象中描述所需的状态,然后 Deployment 控制器将实际状态以受控的速率更改为所需的状态。您可以定义部署以创建新的副本集,或删除现有部署并在新部署中采用其所有资源。一句话:Deployment 主要功能是保证有足够的 Pod 正常对外提供服务。
1.6.1、创建 Depoyment
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
1.6.1.1、 参数示意
nginx-deployment:Deployment 的名称。
replicas: 创建 Pod 的副本数。
selector:定义 Deployment 如何找到要管理的 Pod,与 template 的 label(标签)对应。
template 字段包含以下字段:
app: nginx 使用 label(标签)标记 Pod
spec:表示 Pod 运行一个名字为 nginx 的容器。
image:运行此 Pod 使用的镜像
Port:容器用于发送和接收流量的端口
1.6.1.2、 执行创建命令
[root@k-master-01 ~]
deployment.apps/nginx-deployment created
[root@k-master-01 ~]
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 0/3 0 0 1s
1.6.1.3、 注意
将 kubectl 标志设置--record 为 true 允许您将当前命令记录在正在创建或更新的资源的注释中。这对于将来的检查很有用。
[root@kubernetes-master-01 test]
deployment.apps/nginx-deployment configured
[root@kubernetes-master-01 test]
nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 kubectl apply --filename=deployment.yaml --record=true
1.6.2、查看部署状态
[root@kubernetes-master-01 test]
NAME READY STATUS RESTARTS AGE
nginx-deployment-d46f5678b-6458k 1/1 Running 0 3m28s
nginx-deployment-d46f5678b-hc4fc 1/1 Running 0 3m28s
nginx-deployment-d46f5678b-k7gcg 1/1 Running 0 3m28s
1.6.3、查看部署详情
[root@kubernetes-master-01 test]
Name: nginx-deployment
Namespace: default
CreationTimestamp: Fri, 27 Nov 2020 17:14:56 +0800
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision: 1
kubernetes.io/change-cause: kubectl apply
--filename=deployment.yaml --record=true
Selector: app=nginx
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=nginx Containers: nginx:
Image: nginx
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Progressing True NewReplicaSetAvailable
Available True MinimumReplicasAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-deployment-d46f5678b (3/3 replicas created) Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 7m3s deployment-controller Scaled up replica set nginx-deployment-d46f5678b to 3
1.6.4、更新
一般对应用程序升级或者版本迭代时,会通过 Deployment 对 Pod 进行滚动更新。
1.6.4.1、 设置
[root@kubernetes-master-01 test]
deployment.apps/nginx-deployment image updated
[root@kubernetes-master-01 test]
NAME READY STATUS RESTARTS AGE
nginx-deployment-567bfc79bb-rs59t 0/1 ContainerCreating 0 18s
nginx-deployment-d46f5678b-6458k 1/1 Running 0 9m54s
nginx-deployment-d46f5678b-hc4fc 1/1 Running 0 9m54s
nginx-deployment-d46f5678b-k7gcg 1/1 Running 0 9m54s
1.6.4.2、 修改
[root@kubernetes-master-01 test]
deployment.apps/nginx-deployment edited
[root@kubernetes-master-01 test]
NAME READY STATUS RESTARTS AGE
nginx-deployment-567bfc79bb-9ztk6 1/1 Running 0 85s
nginx-deployment-567bfc79bb-rs59t 1/1 Running 0 109s
nginx-deployment-567bfc79bb-z8wmk 1/1 Running 0 61s
nginx-deployment-7c97c6df7b-pm42c 0/1 ContainerCreating 0 11s
1.6.4.3、 查看更新状态
[root@kubernetes-master-01 test]
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas
have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas
have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas
have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending
termination...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending
termination...
deployment "nginx-deployment" successfully rolled out
1.6.5、回滚
当新版本不稳定时,可以对其进行回滚操作,默认情况下,所有 Deployment 的 rollout 历史都保留在系统中,
可以随时回滚。
1.6.5.1、 查看构建历史
[root@kubernetes-master-01 test]
nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 kubectl apply --filename=deployment.yaml --record=true
2 kubectl apply --filename=deployment.yaml --record=true
3 kubectl apply --filename=deployment.yaml --record=true
1.6.5.2、 回滚到上一个版本
[root@kubernetes-master-01 test]
nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 kubectl apply --filename=deployment.yaml --record=true
2 kubectl apply --filename=deployment.yaml --record=true
3 kubectl apply --filename=deployment.yaml --record=true
[root@kubernetes-master-01 test]
deployment.apps/nginx-deployment rolled back
[root@kubernetes-master-01 test]
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas
have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas
have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas
have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas
have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas
have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas
have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending
termination...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending
termination...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending
termination...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending
termination...
deployment "nginx-deployment" successfully rolled out
[root@kubernetes-master-01 test]
nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 kubectl apply --filename=deployment.yaml --record=true
3 kubectl apply --filename=deployment.yaml --record=true
4 kubectl apply --filename=deployment.yaml --record=true
1.6.5.3、 回滚指定版本
[root@kubernetes-master-01 test]
nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 kubectl apply --filename=deployment.yaml --record=true
3 kubectl apply --filename=deployment.yaml --record=true
4 kubectl apply --filename=deployment.yaml --record=true
[root@kubernetes-master-01 test]
--to-revision=1
deployment.apps/nginx-deployment rolled back
[root@kubernetes-master-01 test]
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas
have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas
have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas
have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas
have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas
have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas
have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending
termination...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending
termination...
deployment "nginx-deployment" successfully rolled out
[root@kubernetes-master-01 test]
nginx-deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Fri, 27 Nov 2020 17:14:56 +0800
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision: 5
kubernetes.io/change-cause: kubectl apply
--filename=deployment.yaml --record=true
Selector: app=nginx
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Progressing True NewReplicaSetAvailable
Available True MinimumReplicasAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-deployment-d46f5678b (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 11m deployment-controller Scaled up
replica set nginx-deployment-567bfc79bb to 1
Normal ScalingReplicaSet 11m deployment-controller Scaled down
replica set nginx-deployment-d46f5678b to 2
Normal ScalingReplicaSet 10m deployment-controller Scaled down
replica set nginx-deployment-d46f5678b to 1
Normal ScalingReplicaSet 10m deployment-controller Scaled up
replica set nginx-deployment-567bfc79bb to 3
Normal ScalingReplicaSet 10m deployment-controller Scaled down
replica set nginx-deployment-d46f5678b to 0
Normal ScalingReplicaSet 10m deployment-controller Scaled up
replica set nginx-deployment-7c97c6df7b to 1
Normal ScalingReplicaSet 5m35s (x2 over 11m) deployment-controller Scaled up
replica set nginx-deployment-567bfc79bb to 2
Normal ScalingReplicaSet 103s (x2 over 9m33s) deployment-controller Scaled
down replica set nginx-deployment-567bfc79bb to 2
Normal ScalingReplicaSet 85s (x2 over 21m) deployment-controller Scaled up
replica set nginx-deployment-d46f5678b to 3
Normal ScalingReplicaSet 85s deployment-controller Scaled down
replica set nginx-deployment-567bfc79bb to 1
Normal ScalingReplicaSet 68s (x12 over 9m33s) deployment-controller (combined
from similar events): Scaled down replica set nginx-deployment-567bfc79bb to 0
1.6.6、扩容
当业务的用户越来越多,目前的后端服务已经无法满足业务要求当前的业务要求,传统的解决办法是将其横
向增加服务器,从而满足我们的业务要求。K8S 中也是支持横向扩容的方法的。
[root@instance-gvpb80ao yaml]
--replicas=5
deployment.apps/nginx-deployment scaled
[root@instance-gvpb80ao yaml]
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 4/5 5 4 31m
[root@kubernetes-master-01 test]
-p '{"spec": {"replicas": 5}}'
deployment.apps/nginx-deployment patched
[root@kubernetes-master-01 test]
NAME READY STATUS RESTARTS AGE
nginx-deployment-d46f5678b-2k6sv 0/1 ContainerCreating 0 5s
nginx-deployment-d46f5678b-4c2pk 1/1 Running 0 10m
nginx-deployment-d46f5678b-mbzs8 1/1 Running 0 9m48s
nginx-deployment-d46f5678b-rd5hm 0/1 ContainerCreating 0 5s
nginx-deployment-d46f5678b-swjdn 1/1 Running 0 10m
1.6.7、暂停部署
[root@kubernetes-master-01 test]
error: deployments.apps "nginx-deployment" is already paused
[root@kubernetes-master-01 test]
deployment.apps/nginx-deployment image updated
[root@kubernetes-master-01 test]
NAME READY STATUS RESTARTS AGE
nginx-deployment-d46f5678b-2k6sv 1/1 Running 0 7m33s
nginx-deployment-d46f5678b-4c2pk 1/1 Running 0 17m
nginx-deployment-d46f5678b-mbzs8 1/1 Running 0 17m
nginx-deployment-d46f5678b-nwzwf 1/1 Running 0 6m11s
nginx-deployment-d46f5678b-p8kwv 1/1 Running 0 6m11s
nginx-deployment-d46f5678b-rd5hm 1/1 Running 0 7m33s
nginx-deployment-d46f5678b-sklzt 1/1 Running 0 6m11s
nginx-deployment-d46f5678b-swjdn 1/1 Running 0 18m
nginx-deployment-d46f5678b-tmhch 1/1 Running 0 6m11s
nginx-deployment-d46f5678b-wwmbk 1/1 Running 0 6m11s
[root@kubernetes-master-01 test]
deployment.apps/nginx-deployment resumed
[root@kubernetes-master-01 test]
NAME READY STATUS RESTARTS AGE
nginx-deployment-7c97c6df7b-45dch 0/1 ContainerCreating 0 2s
nginx-deployment-7c97c6df7b-7sm7l 0/1 ContainerCreating 0 2s
nginx-deployment-7c97c6df7b-9c68n 0/1 ContainerCreating 0 2s
nginx-deployment-7c97c6df7b-mgh4t 0/1 ContainerCreating 0 2s
nginx-deployment-7c97c6df7b-nkxqd 0/1 ContainerCreating 0 2s
nginx-deployment-d46f5678b-2k6sv 1/1 Running 0 8m4s
nginx-deployment-d46f5678b-4c2pk 1/1 Running 0 18m
nginx-deployment-d46f5678b-mbzs8 1/1 Running 0 17m
nginx-deployment-d46f5678b-nwzwf 0/1 Terminating 0 6m42s
nginx-deployment-d46f5678b-p8kwv 1/1 Running 0 6m42s
nginx-deployment-d46f5678b-rd5hm 1/1 Running 0 8m4s
nginx-deployment-d46f5678b-sklzt 1/1 Running 0 6m42s
nginx-deployment-d46f5678b-swjdn 1/1 Running 0 18m
nginx-deployment-d46f5678b-tmhch 1/1 Running 0 6m42s
nginx-deployment-d46f5678b-wwmbk 1/1 Terminating 0 6m42s