文章目录
记一次实操部署Kubernetes_v1.19.2
规划信息
本次部署使用2台机器;1台master 和 1台node ;
master 172.16.0.5 CentOS 7.6
node01 172.16.0.49 CentOS 7.6
安装后的软件版本为:
Kubernetes v1.19.2
flannel v0.13.0
Docker 19.03.11
部署记录
kubeadm 是 Kubernetes 官方支持的安装方式,“二进制” 不是。本文档采用 kubernetes.io 官方推荐的 kubeadm 工具安装 kubernetes 集群。
当前还有其他自动化部署的工具,例如Kubespray等工具;
现在安装Kubernetes 其实并不复杂;本篇文档只是记录;本次安装主要参考了2篇优秀的博客文章;
使用kubeadm安装kubernetes_v1.19.x https://kuboard.cn/install/install-k8s.html
k8s实践(一):Centos7.6部署k8s(v1.14.2)集群 https://blog.51cto.com/3241766/2405624
# 配置主机名 和 hosts 记录, master 和 node 分别执行
[root@VM_0_5_centos ~]# hostnamectl set-hostname master
[root@VM_0_5_centos ~]# more /etc/hostname
master
[root@VM_0_5_centos ~]# logout
Connection to 172.16.0.5 closed.
[root@network-test ~]# ssh 172.16.0.5
root@172.16.0.5's password:
Last login: Wed Oct 14 14:53:50 2020 from 172.16.0.9
[root@master ~]#
[root@master ~]# cat >> /etc/hosts << EOF
> 172.27.0.5 master
> 172.27.0.49 node01
> EOF
[root@master ~]#
# 检查机器网络,确保2台 机器 网络可以正常通信,注意防火墙、安全组等安全策略
安装docker及kubelet
# 使用yum 安装docker,kubectl/kubeadm/kubelet, 等其他依赖组件;
# 在 master 节点和 worker 节点都要执行
# 最后一个参数 1.19.2 用于指定 kubenetes 版本,支持所有 1.19.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.11 docker-ce-cli-19.03.11 containerd.io-1.2.13
mkdir /etc/docker || true
cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors": ["${REGISTRY_MIRROR}"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
EOF
mkdir -p /etc/systemd/system/docker.service.d
# Restart Docker
systemctl daemon-reload
systemctl enable docker
systemctl restart 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
# 可能没有,追加
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.conf
echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf
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
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.19.0
yum install -y kubelet-${1} kubeadm-${1} kubectl-${1}
# 重启 docker,并启动 kubelet
systemctl daemon-reload
systemctl restart docker
systemctl enable kubelet && systemctl start kubelet
docker version
如果此时执行 systemctl status kubelet
命令,将得到 kubelet 启动失败的错误提示,请忽略此错误,因为必须完成后续步骤中 kubeadm init 的操作,kubelet 才能正常启动;
初始化master节点
# 只在 master 节点执行
# 替换 x.x.x.x 为 master 节点的内网IP
# export 命令只在当前 shell 会话中有效,开启新的 shell 窗口后,如果要继续安装过程,请重新执行此处的 export 命令
export MASTER_IP=172.16.0.5
export APISERVER_NAME=master
# Kubernetes 容器组所在的网段,该网段安装完成后,由 kubernetes 创建,事先并不存在于您的物理网络中
export POD_SUBNET=192.168.0.1/16
# 由于最前面已经配置hosts 文件
# echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml#!/bin/bash
# 只在 master 节点执行
# 脚本出错时终止执行
set -e
if [ ${#POD_SUBNET} -eq 0 ] || [ ${#APISERVER_NAME} -eq 0 ]; then
echo -e "\033[31;1m请确保您已经设置了环境变量 POD_SUBNET 和 APISERVER_NAME \033[0m"
echo 当前POD_SUBNET=$POD_SUBNET
echo 当前APISERVER_NAME=$APISERVER_NAME
exit 1
fi
# 查看完整配置选项 https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2
rm -f ./kubeadm-config.yaml
cat <<EOF > ./kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v${1}
imageRepository: registry.aliyuncs.com/k8sxio
controlPlaneEndpoint: "${APISERVER_NAME}:6443"
networking:
serviceSubnet: "10.96.0.0/16"
podSubnet: "${POD_SUBNET}"
dnsDomain: "cluster.local"
EOF
# kubeadm init
# 根据您服务器网速的情况,您需要等候 3 - 10 分钟
kubeadm init --config=kubeadm-config.yaml --upload-certs
# 配置 kubectl
rm -rf /root/.kube/
mkdir /root/.kube/
cp -i /etc/kubernetes/admin.conf /root/.kube/config
# 安装flannel 插件
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
执行完后,使用kubectl get pods --all-namespaces -o wide
查看结果,需要等一段时间,pull 镜像等,确保所有pod 都处于running 状态;
pod 状态异常可查看debug信息或 log 日志,命令参考如下:
kubectl describe pod kube-flannel-ds-fstbb -n kube-system
kubectl logs pod kube-flannel-ds-fstbb -n kube-system
加入worker节点
在 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
该 token 的有效时间为 2 个小时,2小时内,可以使用此 token 初始化任意数量的 worker 节点。
在worker节点执行
# 只在 worker 节点执行
# 替换为 master 节点上 kubeadm token create 命令的输出;
kubeadm join 172.16.0.5:6443 --token mpfjma.4vjjg8flqihor4vt --discovery-token-ca-cert-hash sha256:6f7a8e40a810323672de5eee6f4d19aa2dbdb38411845a1bf5dd63485c43d303
检查结果:
# master节点执行
kubectl get nodes -o wide
默认master节点上是有污点的;(taint:污点的意思)如果一个节点被打上了污点,那么pod是不允许运行在这个节点上面的;
默认情况下集群不会在master上调度pod,如果偏想在master上调度Pod,可以执行如下操作:
查看污点:
[root@master ~]# kubectl describe node master|grep -i taints
Taints: node-role.kubernetes.io/master:NoSchedule
删除默认污点:
[root@master ~]# kubectl taint nodes master node-role.kubernetes.io/master-
node/master untainted
污点机制**
语法:
kubectl taint node [node] key=value[effect]
其中[effect] 可取值: [ NoSchedule | PreferNoSchedule | NoExecute ]
NoSchedule: 一定不能被调度
PreferNoSchedule: 尽量不要调度
NoExecute: 不仅不会调度, 还会驱逐Node上已有的Pod
打污点
[root@master ~]# kubectl taint node master key1=value1:NoSchedule
node/master tainted
[root@master ~]# kubectl describe node master|grep -i taints
Taints: key1=value1:NoSchedule
key为key1,value为value1(value可以为空),effect为NoSchedule表示一定不能被调度
删除污点:
[root@master ~]# kubectl taint nodes master key1-
node/master untainted
[root@master ~]# kubectl describe node master|grep -i taints
Taints: <none>
删除指定key所有的effect,‘-’表示移除所有以key1为键的污点
部署测试pod 验证通信
参考文档中有的在这里是部署 Dashboard ----图形化Kubernetes集群管理工具;有部署ingress 的;
我这里主要是为了部署验证容器网络通信场景,这里就编辑2个yaml 文件,启动2个deployment ,对应nginx和centos ;
[root@master install]# cat centos-test.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: centos-test
spec:
selector:
matchLabels:
app: centos
replicas: 1 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: centos
spec:
containers:
- name: centos
image: centos
command: ["/bin/sh"]
args: ["-c","while true; do echo hello; sleep 10;done"]
[root@master install]#
[root@master install]#
[root@master install]# cat nginx-test.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: nginx-nets
spec:
selector:
matchLabels:
app: nginx
replicas: 1 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
[root@master install]#
# 拉起对应deployment ,可以加 -n 指定namespace ;这里使用默认的default namespace
kubectl apply -f centos-test.yaml
kubectl apply -f nginx-test.yaml
# 查看结果:
[root@master install]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
centos-test-764675d946-jq6xb 1/1 Running 0 3d14h 192.168.0.16 master <none> <none>
centos-test-764675d946-tx4r5 1/1 Running 0 2d20h 192.168.1.2 node01 <none> <none>
nginx-nets-7848d4b86f-ghpc2 1/1 Running 0 3d15h 192.168.0.15 master <none> <none>
nginx-nets-7848d4b86f-wkhvc 1/1 Running 0 2d20h 192.168.1.3 node01 <none> <none>
static-web 1/1 Running 0 3d4h 192.168.0.17 master <none> <none>
[root@master install]#
[root@master install]#
[root@master install]#
[root@master install]# kubectl get deployment -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
centos-test 2/2 2 2 3d14h centos centos app=centos
nginx-nets 2/2 2 2 3d15h nginx nginx app=nginx
[root@master install]#
部署踩坑记录(iptables FORWARD)
新版的docker版本中,会将iptables 中 FORWARD 链 默认策略调为 DROP;会导致pod 通信异常,同node 中pod 访问不通,或跨node pod 通信访问不通;需要将该FORWADR 链策略修改为 ACCEPT;