1. k8s环境平台规划
1.1 单master集群
单个master节点,然后管理多个node节点
1.2 多master集群
多个master节点,管理多个node节点,同时中间多了一个负载均衡的过程
2. 配置要求
环境 |
节点 |
要求 |
测试环境 |
master |
2核 4G 20G |
测试环境 |
node |
4核 8G 40G |
生产环境 |
master |
8核 16G 100G |
生产环境 |
node |
16核 64G 200G |
对于 Kubernetes 初学者推荐在阿里云或腾讯云采购如下配置:(您也可以使用自己的虚拟机、私有云等您最容易获得的 Linux 环境)
- 至少2台 2核4G 的服务器
- Cent OS 7.6 / 7.7 / 7.8
3. Kubernetes集群主要有两种方式
3.1 kubeadm
kubeadm是一个K8S部署工具,提供kubeadm init 和 kubeadm join,用于快速部署Kubernetes集群
官网地址
3.2 二进制包
从github下载发行版的二进制包,手动部署每个组件,组成Kubernetes集群。
Kubeadm降低部署门槛,但屏蔽了很多细节,遇到问题很难排查。如果想更容易可控,推荐使用二进制包部署Kubernetes集群,虽然手动部署麻烦点,期间可以学习很多工作原理,也利于后期维护。
4. kubeadm、 kubectl 、kubelet 区别
-
kubeadm
kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具。
这个工具能通过两条指令完成一个kubernetes集群的部署:
# 创建一个 Master 节点
kubeadm init
# 将一个 Node 节点加入到当前集群中
kubeadm join <Master节点的IP和端口 >
-
kubectl
kubectl是Kubernetes集群的命令行工具,通过kubectl能够对集群本身进行管理,并能够在集群上进行容器化应用的安装和部署
-
kubelet
Kubelet:master派到node节点代表,管理本机容器
- 一个集群中每个节点上运行的代理,它保证容器都运行在Pod中
- 负责维护容器的生命周期,同时也负责Volume(CSI) 和 网络(CNI)的管理
5. 使用kubeadm方式搭建K8s集群主要分为以下几步
- 准备三台虚拟机,同时安装操作系统CentOS 7.x
- 对三个安装之后的操作系统进行初始化操作
- 在三个节点安装 docker kubelet kubeadm kubectl
- 在master节点执行kubeadm init命令初始化
- 在node节点上执行 kubeadm join命令,把node节点添加到当前集群
- 配置CNI网络插件,用于节点之间的连通【失败了可以多试几次】
- 通过拉取一个nginx进行测试,能否进行外网测试
5. 安装步骤
1. 检查 centos / hostname
# 在 master 节点和 worker 节点都要执行
cat /etc/redhat-release
# 此处 hostname 的输出将会是该机器在 Kubernetes 集群中的节点名字
# 不能使用 localhost 作为节点的名字
hostname
# 请使用 lscpu 命令,核对 CPU 信息
# Architecture: x86_64 本安装文档不支持 arm 架构
# CPU(s): 2 CPU 内核数量不能低于 2
lscpu
修改 hostname
# 修改 hostname
hostnamectl set-hostname your-new-host-name
# 查看修改结果
hostnamectl status
# 设置 hostname 解析
echo "127.0.0.1 $(hostname)" >> /etc/hosts
2. 安装docker及kubelet
安装参考:https://www.kuboard.cn/install/history-k8s/install-k8s-1.18.x.html
-
认真核对如下选项
- 我的任意节点 centos 版本为 7.6 / 7.7 或 7.8
- 我的任意节点 CPU 内核数量大于等于 2,且内存大于等于 4G
- 我的任意节点 hostname 不是 localhost,且不包含下划线、小数点、大写字母
- 我的任意节点都有固定的内网 IP 地址
- 我的任意节点都只有一个网卡,如果有特殊目的,我可以在完成 K8S 安装后再增加新的网卡
- 我的任意节点上 Kubelet使用的 IP 地址 可互通(无需 NAT 映射即可相互访问),且没有防火墙、安全组隔离
- 我的任意节点不会直接使用 docker run 或 docker-compose 运行容器
-
使用 root 身份在所有节点执行如下代码,以安装软件:
- docker
- nfs-utils
- kubectl / kubeadm / kubelet
-
手动执行以下代码,结果与快速安装相同。请将脚本第} 替换成您需要的版本号,例如 1.18.9
docker hub 镜像请根据自己网络的情况任选一个
# 在 master 节点和 worker 节点都要执行
# 最后一个参数 1.18.9 用于指定 kubenetes 版本,支持所有 1.18.x 版本的安装
# 腾讯云 docker hub 镜像
# export REGISTRY_MIRROR="https://mirror.ccs.tencentyun.com"
# DaoCloud 镜像
# export REGISTRY_MIRROR="http://f1361db2.m.daocloud.io"
# 阿里云 docker hub 镜像
export REGISTRY_MIRROR=https://registry.cn-hangzhou.aliyuncs.com
#!/bin/bash
# 在 master 节点和 worker 节点都要执行
# 安装 docker
# 参考文档如下
# https://docs.docker.com/install/linux/docker-ce/centos/
# https://docs.docker.com/install/linux/linux-postinstall/
# 卸载旧版本
yum remove -y docker \
docker-client \
docker-client-latest \
docker-ce-cli \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine
# 设置 yum repository
yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装并启动 docker
yum install -y docker-ce-19.03.8 docker-ce-cli-19.03.8 containerd.io
systemctl enable docker
systemctl start docker
# 安装 nfs-utils
# 必须先安装 nfs-utils 才能挂载 nfs 网络存储
yum install -y nfs-utils
yum install -y wget
# 关闭 防火墙
systemctl stop firewalld
systemctl disable firewalld
# 关闭 SeLinux 容器可以读取主机文件系统
setenforce 0
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
# 关闭 swap 关闭交换空间的使用
swapoff -a
yes | cp /etc/fstab /etc/fstab_bak
cat /etc/fstab_bak |grep -v swap > /etc/fstab
# 修改 /etc/sysctl.conf
# 如果有配置,则修改
sed -i "s#^net.ipv4.ip_forward.*#net.ipv4.ip_forward=1#g" /etc/sysctl.conf
sed -i "s#^net.bridge.bridge-nf-call-ip6tables.*#net.bridge.bridge-nf-call-ip6tables=1#g" /etc/sysctl.conf
sed -i "s#^net.bridge.bridge-nf-call-iptables.*#net.bridge.bridge-nf-call-iptables=1#g" /etc/sysctl.conf
sed -i "s#^net.ipv6.conf.all.disable_ipv6.*#net.ipv6.conf.all.disable_ipv6=1#g" /etc/sysctl.conf
sed -i "s#^net.ipv6.conf.default.disable_ipv6.*#net.ipv6.conf.default.disable_ipv6=1#g" /etc/sysctl.conf
sed -i "s#^net.ipv6.conf.lo.disable_ipv6.*#net.ipv6.conf.lo.disable_ipv6=1#g" /etc/sysctl.conf
sed -i "s#^net.ipv6.conf.all.forwarding.*#net.ipv6.conf.all.forwarding=1#g" /etc/sysctl.conf
# 可能没有,追加
#主要是目的是 当linux主机有多个网卡时一个网卡收到的信息是否能够传递给其他的网卡 如果设置成1 的话 可以进行数据包转发 可以实现VxLAN 等功能.将桥接的 IPv4 流量传递到 iptables 的链
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.conf
#意味着二层的网桥在转发包时也会被iptables的FORWARD规则所过滤
echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf
#设置禁用IPv6
echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.lo.disable_ipv6 = 1" >> /etc/sysctl.conf
#IPv6 转发必须要启用
echo "net.ipv6.conf.all.forwarding = 1" >> /etc/sysctl.conf
# 执行命令以应用
sysctl -p
# 配置K8S的yum源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
# 卸载旧版本
yum remove -y kubelet kubeadm kubectl
# 安装kubelet、kubeadm、kubectl
# 将 ${1} 替换为 kubernetes 版本号,例如 1.17.2
yum install -y kubelet-${1} kubeadm-${1} kubectl-${1}
# 修改docker Cgroup Driver为systemd
# # 将/usr/lib/systemd/system/docker.service文件中的这一行 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
# # 修改为 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --exec-opt native.cgroupdriver=systemd
# 如果不修改,在添加 worker 节点时可能会碰到如下错误
# [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd".
# Please follow the guide at https://kubernetes.io/docs/setup/cri/
sed -i "s#^ExecStart=/usr/bin/dockerd.*#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --exec-opt native.cgroupdriver=systemd#g" /usr/lib/systemd/system/docker.service
# 设置 docker 镜像,提高 docker 镜像下载速度和稳定性
# 如果您访问 https://hub.docker.io 速度非常稳定,亦可以跳过这个步骤
curl -sSL https://kuboard.cn/install-script/set_mirror.sh | sh -s ${REGISTRY_MIRROR}
# 重启 docker,并启动 kubelet
systemctl daemon-reload
systemctl restart docker
systemctl enable kubelet && systemctl start kubelet
docker version
-
初始化 master 节点
# 只在 master 节点执行
# 替换 x.x.x.x 为 master 节点实际 IP(请使用内网 IP)
# export 命令只在当前 shell 会话中有效,开启新的 shell 窗口后,如果要继续安装过程,请重新执行此处的 export 命令
export MASTER_IP=x.x.x.x
# 替换 apiserver.demo 为 您想要的 dnsName
export APISERVER_NAME=apiserver.demo
# Kubernetes 容器组所在的网段,该网段安装完成后,由 kubernetes 创建,事先并不存在于您的物理网络中
export POD_SUBNET=10.100.0.1/16
echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts
curl -sSL https://kuboard.cn/install-script/v1.18.x/init_master.sh | sh -s 1.18.9
-
检查 master 初始化结果
# 只在 master 节点执行
# 执行如下命令,等待 3-10 分钟,直到所有的容器组处于 Running 状态
watch kubectl get pod -n kube-system -o wide
# 查看 master 节点初始化结果
kubectl get nodes -o wide
-
初始化 worker节点
获得 join命令参数
在 master 节点上执行
# 只在 master 节点执行
kubeadm token create --print-join-command
可获取kubeadm join 命令及参数,如下所示
# kubeadm token create 命令的输出
kubeadm join apiserver.demo:6443 --token mpfjma.4vjjg8flqihor4vt --discovery-token-ca-cert-hash sha256:6f7a8e40a810323672de5eee6f4d19aa2dbdb38411845a1bf5dd63485c43d303
针对所有的 worker 节点执行
# 只在 worker 节点执行
# 替换 x.x.x.x 为 master 节点的内网 IP
export MASTER_IP=x.x.x.x
# 替换 apiserver.demo 为初始化 master 节点时所使用的 APISERVER_NAME
export APISERVER_NAME=apiserver.demo
echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts
# 替换为 master 节点上 kubeadm token create 命令的输出
kubeadm join apiserver.demo:6443 --token mpfjma.4vjjg8flqihor4vt --discovery-token-ca-cert-hash sha256:6f7a8e40a810323672de5eee6f4d19aa2dbdb38411845a1bf5dd63485c43d303
-
检查初始化结果
在 master 节点上执行
# 只在 master 节点执行
kubectl get nodes -o wide
3. 测试kubernetes集群
-
在Kubernetes集群中创建一个pod,验证是否正常运行:
# 下载nginx 【会联网拉取nginx镜像】
kubectl create deployment nginx --image=nginx
# 查看状态
kubectl get pod
-
如果我们出现Running状态的时候,表示已经成功运行了
-
将端口暴露出去,让其它外界能够访问
# 暴露端口
kubectl expose deployment nginx --port=80 --type=NodePort
# 查看一下对外的端口
kubectl get pod,svc
4. 安装过程中遇到的错误
#查看错误日志
journalctl -xefu kubelet
-
Cgroup Driver和kubelet的Cgroup Driver不一致
failed to create kubelet: misconfiguration: kubelet cgroup driver: "cgroupfs" is different from docker cgroup driver: "systemd"
vim /var/lib/kubelet/kubeadm-flags.env
修改成以下内容,增加 --cgroup-driver=systemd
KUBELET_KUBEADM_ARGS="--cgroup-driver=systemd --network-plugin=cni --pod-infra-container-image=registry.aliyuncs.com/k8sxio/pause:3.2"
-
Calico 问题
Readiness probe failed: caliconode is not ready: BIRD is not ready: BGP not established with 10.1.126.32
master执行
kubectl set env daemonset/calico-node -n kube-system IP_AUTODETECTION_METHOD=interface=ens*
6. 常用命令
kubectl命令的语法如下
kubectl [command] [type] [name] [flags]
- comand:指定要对资源执行的操作,例如create、 get、delete
- type:指定资源类型,比如deployment、pod、 service
- name:指定资源的名称,名称大小写敏感
- flags:指定额外的可选参数
移除worker节点
# 只在 worker 节点执行
kubeadm reset -f
# 只在 master 节点执行
kubectl get nodes -o wide
# 只在 master 节点执行 demo 节点名称
kubectl delete node demo-worker-x-x
node
命令 |
说明 |
查看服务器节点 |
kubectl get nodes |
查看服务器节点详情 |
kubectl get nodes -o wide |
查看服务器节点 |
kubectl get nodes |
移除节点 |
kubectl delete node demo-worker-x-x |
节点打标签 |
kubectl label nodes <节点名称> labelName=<标签名称> |
查看节点标签 |
kubectl get node --show-labels |
删除节点标签 |
kubectl label node <节点名称> labelName- |
pod
命令 |
说明 |
查看所有pod节点 |
kubectl get pods -A |
查看所有名称空间下的pod |
kubectl get pod --all-namespaces |
根据命名空间查看pod |
kubectl get pod -n test |
查看异常pod节点的日志 |
kubectl describe pod <pod名称> -n <名称空间> |
根据yaml文件创建pod |
kubectl apply -f <文件名称> |
根据yaml文件删除pod |
kubectl delete -f <文件名称> |
删除pod节点 |
kubectl delete pod <pod名称> -n <名称空间> |
查看异常pod节点的日志 |
kubectl describe pod <pod名称> -n <名称空间> |
进入默认命名空间的pod节点 |
kubectl exec -it <pod名称> – /bin/bash |
进入某个特定命名空间下的pod节点 |
kubectl exec -it <pod名称> -n <命名空间> – /bin/bash |
普通方式创建pod |
kubectl run <pod名称> --image=<镜像名称> |
deployment
说明 |
命令 |
deployment部署pod(具有自愈能力,宕机自动拉起) |
kubectl create deployment <pod名称> --image=<镜像名称> |
deployment部署pod(多副本) |
kubectl create deployment <pod名称> --image=<镜像名称> --replicas=3 |
查看deployment部署 |
kubectl get deploy |
删除deployment部署 |
kubectl delete deploy <pod名称> |
deployment扩容\缩容pod |
kubectl scale deploy/<pod名称> --replicas=<5> |
deployment扩容\缩容pod |
kubectl edit deploy <pod名称> |
deployment滚动更新pod |
kubectl set image deploy/<pod名称> <容器名称>=<镜像名称:版本号> --record |
deployment查看pod回退版本 |
kubectl rollout history deploy/<pod名称> |
deployment查看pod回退版本详情 |
kubectl rollout history deploy/<pod名称> --revision=1 |
deployment回退pod到上一个版本 |
kubectl rollout undo deploy/<pod名称> |
deployment回退pod到指定版本 |
kubectl rollout undo deploy/<pod名称> --to-revision=1 |
deployment暴露pod集群内部访问(ClusterIP) |
kubectl expose deployment <pod名称> --port=8080 --target-port=80 --type=ClusterIP |
deployment暴露pod外网访问(NodePort) |
kubectl expose deployment <pod名称> --port=8080 --target-port=80 --type=NodePort |
svc
说明 |
命令 |
查看服务 |
kubectl get svc |
查看服务详情 |
kubectl get svc -o wide |
查看所有名称空间下的服务 |
kubectl get svc --all-namespaces |
namespace
说明 |
命令 |
查看名称空间 |
kubectl get namespace |
查看名称空间 |
kubectl get ns |
创建名称空间 |
kubectl create ns <名称> |
删除名称空间 |
kubectl delete ns <名称> |