k8s 部署
当前部署版本为当前次新版本,因为后面需要使用 kubeadm 做 kubernetes 版本升级演示。
目前官方最新版本为 1.18.0 本次使用1.17.3
1、 基础环境准备
# ufw disable #swapoff -a # vim /etc/fstab#/swapfile注释
# selinux=disabled
# timezone 设置 timedatectl set-timezone Asia/Shanghai
# ntpdate time1.aliyun.com
# 内核参数优化 官方示例如下:
# 设置必需的sysctl参数,这些参数在重新启动后仍然存在。
cat > /etc/sysctl.d/99-kubernetes-cri.conf <<EOF
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
2、 部署 harbor作为仓库 及 haproxy 高可用反向代理
3、在所有 master 安装指定版本的 kubeadm 、kubelet、kubectl、docker
4、在所有 node 节点安装指定版本的 kubeadm 、kubelet、docker,在 node 节点 kubectl 为
可选安装,看是否需要在 node 执行 kubectl 命令进行集群管理及 pod 管理等操作。
5、master 节点运行 kubeadm init 初始化命令
6、验证 master 节点状态
7、在 node 节点使用 kubeadm 命令将自己加入 k8s master(需要使用 master 生成 token 认
证)
8、验证 node 节点状态
9、创建 pod 并测试网络通信
10、部署 web 服务 Dashboard
11、k8s 集群升级
1. harbor 及反向代理(haproxy+keepalived)
1.1 反向代理(haproxy+keepalived)
keepalived配置
root@haproxy:~# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
}
vrrp_instance VI_1 {
state MASTER
interface eth0
garp_master_delay 10
smtp_alert
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.20.21.248 dev eth0 label eth0:1
}
}
~
haproxy
root@haproxy:~# vim /etc/haproxy/haproxy.cfg
listen stats
mode http
bind 0.0.0.0:9999
stats enable
log global
stats uri /haproxy-status
stats auth haadmin:123456
listen k8s-6443
bind 172.20.21.248:6443
mode tcp
balance roundrobin
server master1 172.20.21.101:6443 check inter 2s fall 3 rise 5
server master2 172.20.21.102:6443 check inter 2s fall 3 rise 5
server master3 172.20.21.103:6443 check inter 2s fall 3 rise 5
1.2 habor
#harbor-offline-installer-v1.7.6
#cd /usr/local/src
root@harbor:/usr/local/src# pwd
/usr/local/src
root@harbor:/usr/local/src# ls
harbor harbor-offline-installer-v1.7.6.tgz
root@harbor:/usr/local/src# ln -sv /usr/local/src/harbor /usr/local/harbor
root@harbor:/usr/local/src/harbor# ls
common docker-compose.clair.yml docker-compose.yml harbor.v1.7.6.tar.gz LICENSE prepare
docker-compose.chartmuseum.yml docker-compose.notary.yml harbor.cfg install.sh open_source_license
#更改hahabor.cfg相关内容
#apt install docker-compose
./install.sh
2. 安装 kubeadm 等组件
2.1 所有 master 和 node 节点安装 docker
#!/bin/bash
#
#********************************************************************
#Author: caozhiming
#QQ: 200530287
#Date: 2020-03-07
#FileName: onekey-install-docker.sh
#Description: The test script
#Copyright (C): 2020 All rights reserved
#********************************************************************
#Step 1: 安装必要的一些系统工具
sudo apt-get update
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
# step 2: 安装GPG证书
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# Step 3: 写入软件源信息
sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# Step 4: 更新并安装Docker-CE
sudo apt-get -y update
sudo apt-get -y install docker-ce docker-ce-cli
#step 5 :设置加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://gd0c8njk.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
# 安装指定版本的Docker-CE:
# Step 1: 查找Docker-CE的版本:
# apt-cache madison docker-ce
# docker-ce | 17.03.1~ce-0~ubuntu-xenial | https://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages
# docker-ce | 17.03.0~ce-0~ubuntu-xenial | https://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial/stable amd64 Packages
# Step 2: 安装指定版本的Docker-CE: (VERSION例如上面的17.03.1~ce-0~ubuntu-xenial)
# sudo apt-get -y install docker-ce=[VERSION]
---------------------------------------------------------------------------->华丽分割线
https://kubernetes.io/zh/docs/setup/production-environment/container-runtimes/
cat > /etc/docker/daemon.json <<EOF #cgroupdriver=systemd
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
root@node1:~# systemctl daemon-reload
root@node1:~# systemctl restart docker
所有master服务器点安装 kubelet kubeadm kubectl,node节点kubectl非必须
# apt-get update && apt-get install -y apt-transport-https
# curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
# cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF #手动输入 EOF
# apt-get update
#安装指定版本 kubeadm
查看版本信息
# apt-cache madison kubeadm
安装 kubeadm kubectl kubelet
# apt install kubeadm=1.17.3-00 kubectl=1.17.3-00 kubelet=1.17.3-00
启动并验证 kubelet
# systemctl start kubelet && systemctl enable kubelet && systemctl status kubelet
2.3 master 节点运行 kubeadm init 初始化命令
kubeadm命令补全
Available Commands:
alpha #kubeadm 处于测试阶段的命令
completion #bash 命令补全,需要安装 bash-completion
#mkdir /data/scripts -p
#kubeadm completion bash > /data/scripts/kubeadm_completion.sh
#source /data/scripts/kubeadm_completion.sh
#vim /etc/profile
source /data/scripts/kubeadm_completion.sh
config #管理 kubeadm 集群的配置,该配置保留在集群的 ConfigMap 中
#kubeadm config print init-defaults
help Help about any command
init #启动一个 Kubernetes 主节点
join #将节点加入到已经存在的 k8s master
reset 还原使用 kubeadm init 或者 kubeadm join 对系统产生的环境变化
token #管理 token
upgrade #升级 k8s 版本
version #查看版本信息
kubeadm init 命令简介
# -apiserver-advertise-address string #K8S API Server 将要监听的监听的本机 IP
# --apiserver-bind-port int32 #API Server 绑定的端口,默认为 6443
--apiserver-cert-extra-sans stringSlice #可选的证书额外信息,用于指定 API Server 的服务器证
书。可以是 IP 地址也可以是 DNS 名称。
--cert-dir string #证书的存储路径,缺省路径为 /etc/kubernetes/pki
--certificate-key string #定义一个用于加密 kubeadm-certs Secret 中的控制平台证书的密钥
--config string #kubeadm #配置文件的路径
# --control-plane-endpoint string #为控制平台指定一个稳定的 IP 地址或 DNS 名称,即配置一
个可以长期使用切是高可用的 VIP 或者域名,k8s 多 master 高可用基于此参数实现
--cri-socket string #要连接的 CRI(容器运行时接口,Container Runtime Interface, 简称 CRI)套
接字的路径,如果为空,则 kubeadm 将尝试自动检测此值,"仅当安装了多个 CRI 或具有非
标准 CRI 插槽时,才使用此选项"
--dry-run #不要应用任何更改,只是输出将要执行的操作,其实就是测试运行。
--experimental-kustomize string #用于存储 kustomize 为静态 pod 清单所提供的补丁的路径。
--feature-gates string #一组用来描述各种功能特性的键值(key=value)对,选项是:
IPv6DualStack=true|false (ALPHA - default=false)
# --ignore-preflight-errors strings #可以忽略检查过程 中出现的错误信息,比如忽略 swap,如
果为 all 就忽略所有
# --image-repository string #设置一个镜像仓库,默认为 k8s.gcr.io
# --kubernetes-version string #指定安装 k8s 版本,默认为 stable-1
--node-name string #指定 node 节点名称
# --pod-network-cidr #设置 pod ip 地址范围
# --service-cidr #设置 service 网络地址范围
--service-dns-domain string #设置 k8s 内部域名,默认为 cluster.local,会有相应的 DNS 服务
(kube-dns/coredns)解析生成的域名记录。
--skip-certificate-key-print #不打印用于加密的 key 信息
--skip-phases strings #要跳过哪些阶段
--skip-token-print #跳过打印 token 信息
--token #指定 token
--token-ttl #指定 token 过期时间,默认为 24 小时,0 为永不过期
--upload-certs #更新证书
#全局可选项:
--add-dir-header #如果为 true,在日志头部添加日志目录
--log-file string #如果不为空,将使用此日志文件
--log-file-max-size uint #设置日志文件的最大大小,单位为兆,默认为 1800 兆,0 为没有限
制
--rootfs #宿主机的根路径,也就是绝对路径
--skip-headers #如果为 true,在 log 日志里面不显示标题前缀
--skip-log-headers #如果为 true,在 log 日志里里不显示标题
master 节点 镜像 下载
# kubeadm config images list --kubernetes-version v1.17.3 #查看当前版本所需镜像
# cat images-download.sh
#!/bin/bash
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.17.3
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-
manager:v1.17.3
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.17.3
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.17.3
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.1
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.4.3-0
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.6.5
# bash images-download.sh
2.2 高可用master 初始化
首先基于 keepalived 实现高可用 VIP,然后实现三台 k8s master 基于 VIP 实现高可用
基于命令初始化高可用 master 方式
kubeadm init --apiserver-advertise-address=172.20.21.101 --control-plane-endpoint=172.20.21.248 --apiserver-bind-port=6443 --kubernetes-version=v1.17.3 --pod-network-cidr=10.10.0.0/16 --service-cidr=192.168.0.0/16 --service-dns-domain=caozhiming.local --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers --ignore-preflight-errors=swap
基于文件初始化高可用 master 方式
# kubeadm config print init-defaults #输出默认初始化配置
# kubeadm config print init-defaults > kubeadm-init.yaml #将默认配置输出至文件
# cat kubeadm-init.yaml #修改后的初始化文件内容
apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 172.31.3.101
bindPort: 6443
nodeRegistration:
criSocket: /var/run/dockershim.sock
name: k8s-master1.magedu.net
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controlPlaneEndpoint: 172.31.7.248:6443 #添加基于 VIP 的 Endpoint
controllerManager: {}
dns:
type: CoreDNS
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.17.3
networking:
dnsDomain: caozhiming.local
podSubnet: 10.10.0.0/16
serviceSubnet: 192.168.0.0/16
scheduler: {}
# kubeadm init --config kubeadm-init.yaml #基于文件执行 k8s master 初始化
3. 配置 kube-config 文件及网络组件
配置 kube-config 文件:
# mkdir -p $HOME/.kube
# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# sudo chown $(id -u):$(id -g) $HOME/.kube/config
# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master1.magedu.net NotReady master 10m v1.17.3
部署网络组件 flannel:
https://github.com/coreos/flannel/
# kubectl apply -f flannel.yml
验证 master 节点状态:
# kubectl get node
NAME STATUS ROLES AGE VERSION
kubeadm-master1.magedu.net Ready master 7m56s v1.17.3
4. 当前 maste 生成证书用于添加新控制节点
# kubeadm init phase upload-certs --upload-certs
W0322 11:38:39.512764 18966 validation.go:28] Cannot validate kube-proxy config - no
validator is available
W0322 11:38:39.512817 18966 validation.go:28] Cannot validate kubelet config - no validator
is available
[upload-certs] Storing the certificates in Secret "kubeadm-certs" in the "kube-system"
Namespace
[upload-certs] Using certificate key:
b66cd885cbd3b94cace2ddfad3037935ba3dabc63bf2aee0c28878b6857ac53b
5. 添加新master节点
5.1其他master节点所需命令
kubeadm join 172.20.21.248:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:1772d5f2a769817e35a9b8a5e64abbe43501c729de5866282fabdff6cba38603 \
--control-plane --certificate-key 78b093813697ae6dcfdcf19e3bfdd2719c879a39f1d3dcd0c709d29b1de33c99
--certificate-key+ 上述命令key
5.2 node节点
kubeadm join 172.20.21.248:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:1772d5f2a769817e35a9b8a5e64abbe43501c729de5866282fabdff6cba38603
5.3 验证 节点状态
root@k8s-master1-caozhiming:~# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master1-caozhiming.net Ready master 22h v1.17.3
k8s-master2-caozhiming.net Ready master 21h v1.17.3
k8s-master3-caozhiming.net Ready master 21h v1.17.3
k8s-node1 Ready <none> 19h v1.17.3
k8s-node2 Ready <none> 18h v1.17.3
k8s-node3 Ready <none> 18h v1.17.3
5.4 k8s 创建容器并测试网络
创建测试容器,测试网络连接是否可以通信
# kubectl run net-test1 --image=alpine --replicas=2 sleep 360000
root@k8s-master1-caozhiming:~# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
net-test1-5fcc69db59-8zbtj 1/1 Running 1 18h 10.10.4.3 k8s-node2 <none> <none>
net-test1-5fcc69db59-s5pmn 1/1 Running 1 18h 10.10.3.3 k8s-node1 <none> <none>
root@k8s-master1-caozhiming:~# kubectl exec -it net-test1-5fcc69db59-8zbtj sh
/ # ping www.baidu.com
PING www.baidu.com (39.156.66.14): 56 data bytes
64 bytes from 39.156.66.14: seq=0 ttl=127 time=6.214 ms
64 bytes from 39.156.66.14: seq=1 ttl=127 time=6.805 ms
64 bytes from 39.156.66.14: seq=2 ttl=127 time=6.372 ms
^C
--- www.baidu.com ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 6.214/6.463/6.805 ms
/ #
6. K8S重新加入MASTER节点,避免ETCD错误
6.1 kubernetes节点信息
root@k8s-master1-caozhiming:~# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master1-caozhiming.net Ready master 22h v1.17.3
k8s-master2-caozhiming.net Ready master 21h v1.17.3
k8s-master3-caozhiming.net Ready master 21h v1.17.3
k8s-node1 Ready <none> 19h v1.17.3
k8s-node2 Ready <none> 18h v1.17.3
k8s-node3 Ready <none> 18h v1.17.3
6.2 删除master
# master1执行
kubectl drain k8s-master3.caozhiming.net
kubectl delete node k8s-master3.caozhiming.net
# master3执行
kubeadm reset
rm -rf /etc/kubernetes/manifests/
6.3 删除etcd信息
进入容器
# kubectl exec -it k8s-master1.caozhiming.net sh -n kube-system
列出节点
# etcdctl --endpoints 127.0.0.1:2379 --cacert /etc/kubernetes/pki/etcd/ca.crt --cert /etc/kubernetes/pki/etcd/server.crt --key /etc/kubernetes/pki/etcd/server.key member list
删除相应节点
# etcdctl --endpoints 127.0.0.1:2379 --cacert /etc/kubernetes/pki/etcd/ca.crt --cert /etc/kubernetes/pki/etcd/server.crt --key /etc/kubernetes/pki/etcd/server.key member remove f952777daab3e8fa
6.4 获取添加master的命令
# master1
kubeadm init phase upload-certs --upload-certs
#kubeadm join 172.20.21.248:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:1772d5f2a769817e35a9b8a5e64abbe43501c729de5866282fabdff6cba38603 \
--control-plane --certificate-key +上述命令产生的key
7. 报错总结
-
基础环境很重要
(1)检查hosts,查看主机名和ip是否对应 (2)swap分区是否关闭(/etc/fstab注释swap行) (3)检查防火墙和selinux是否关闭 (4)时间同步 时区 (5)docker的CGROUPs=systemd设置 (6)内核参数优化 开启ipv4.ip_forward转发功能
-
node节点:8446 cni.go:237] Unable to update cni config: no networks found in /etc/cni/net.
一般情况下是因为 node节点添加到master时 未拉取到镜像 # docker pull quay.io/coreos/flannel:v0.12.0
-
做过内核优化的请忽略
# 设置必需的sysctl参数,这些参数在重新启动后仍然存在。
cat > /etc/sysctl.d/kubernetes-cri.conf <<EOF
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
# sysctl -p 使之生效