工具包:crictl-v1.21.0-linux-386.tar.gz

calico.yaml

kubernetes-dashboard.yaml

1、前置知识点

1.1 生成环境下可部署k8s的两种方式

  • kubeadm
Kubeadm是一个K8s部署工具,提供kubeadm init和kubeadm join,用于快速部署Kubernetes集群。
  • 二进制包
从github下载发行版的二进制包,手动部署每个组件,组成Kubernetes集群。

kubeadm工具功能

  • **kubeadm init**:初始化一个master节点
  • **kubeadm join**:将工作节点加入集群
  • **kubeadm upgrade**:升级k8s版本
  • **kubeadm token**:管理**kubeadm join**使用的令牌
  • **kubeadm reset**:清空**kubeadm init****kubeadm join**对主机所做的任何更改
  • **kubeadm version**:打印**kubeadm**版本
  • **kubeadm alpha**:预览可用的新功能

1.2 准备环境

服务器配置:

  • 建议最小配置:2核CPU、2G内存、20G硬盘
  • 最好可以连接外网,方便拉取镜像,不能,提前下载镜像导入节点

软件环境:

软件 版本
OS CentOS7.9_x64 (mini)
Docker 20-ce
Kubernetes 1.21

服务器规划:

角色 IP
k8s-master1 192.168.6.20
k8s-node1 192.168.6.21
k8s-node2 192.168.6.22

架构图:

1、部署一套单Master的K8s集群-kubeadm - 图1

1.3 操作系统初始化配置

  1. # 关闭防火墙
  2. systemctl stop firewalld
  3. systemctl disable firewalld
  4. # 关闭selinux
  5. sed -i 's/enforcing/disabled/' /etc/selinux/config # 永久
  6. setenforce 0 # 临时
  7. # 关闭swap
  8. swapoff -a # 临时
  9. sed -ri 's/.*swap.*/#&/' /etc/fstab # 永久
  10. # 根据规划设置主机名
  11. hostnamectl set-hostname <hostname>
  12. # 在master添加hosts
  13. cat >> /etc/hosts << EOF
  14. 192.168.6.20 k8s-master1
  15. 192.168.6.21 k8s-node1
  16. 192.168.6.22 k8s-node2
  17. EOF
  18. # 将桥接的IPv4流量传递到iptables的链
  19. cat > /etc/sysctl.d/k8s.conf << EOF
  20. net.bridge.bridge-nf-call-ip6tables = 1
  21. net.bridge.bridge-nf-call-iptables = 1
  22. EOF
  23. sysctl --system # 生效
  24. # 时间同步
  25. yum install ntpdate -y
  26. ntpdate time.windows.com

2、安装Docker/kubeadm/kubelet【所有节点】

这里我们使用docker作为容器引擎,也可以使用别的,比如:containerd

2.1 安装docker

  1. wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
  2. yum -y install docker-ce
  3. systemctl enable docker && systemctl start docker

CentOS8安装docker:<font style="color:rgb(238, 153, 0);">yum install -y docker-ce --allowerasing</font>或者<font style="color:rgb(238, 153, 0);">yum install -y docker-ce --nobest</font>

否则报错:(尝试在命令行中添加 ‘—allowerasing’ 来替换冲突的软件包 或 ‘—skip-broken’ 来跳过无法安装的软件包 或 ‘—nobest’ 来不只使用软件包的最佳候选)

配置镜像下载加速器:

  1. cat > /etc/docker/daemon.json << EOF
  2. {
  3. "registry-mirrors": ["https://3fc19s4g.mirror.aliyuncs.com"]
  4. }
  5. EOF
  6. systemctl restart docker
  7. docker info

2.2 添加YUM软件源-阿里云

  1. cat > /etc/yum.repos.d/kubernetes.repo << EOF
  2. [kubernetes]
  3. name=Kubernetes
  4. baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
  5. enabled=1
  6. gpgcheck=0
  7. repo_gpgcheck=0
  8. gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
  9. EOF

2.3 安装kubeadm/kubelet/kubectl

由于版本更新频繁,这里指定版本号部署

  1. yum list kubelet --showduplicates | sort -r # 查看版本
  2. yum install -y kubelet-1.21.0 kubeadm-1.21.0 kubectl-1.21.0
  3. systemctl enable kubelet

3、部署kubernetes master 【master节点】

在master(192.168.6.20)节点上执行

  1. kubeadm init \
  2. --apiserver-advertise-address=192.168.6.20 \
  3. --image-repository registry.aliyuncs.com/google_containers \
  4. --kubernetes-version v1.21.0 \
  5. --service-cidr=10.96.0.0/12 \
  6. --pod-network-cidr=10.244.0.0/16 \
  7. --ignore-preflight-errors=all
  • —apiserver-advertise-address 集群通讯地址
  • —image-repository 由于默认拉取镜像是k8s.gcr.io国内无法访问,这里指定阿里云镜像仓库地址
  • —kubernetes-version k8s版本,与上面安装的一致
  • —service-cidr 集群内部虚拟网络,pod统一访问
  • —pod-network-cidr pod网络,与下面部署的CNI网络组件yaml中保持一致

或者使用配置文件引导

  1. vi kubeadm.conf
  2. apiVersion: kubeadm.k8s.io/v1beta2
  3. kind: ClusterConfiguration
  4. kubernetesVersion: v1.21.0
  5. imageRepository: registry.aliyuncs.com/google_containers
  6. networking:
  7. podSubnet: 10.244.0.0/16
  8. serviceSubnet: 10.96.0.0/12
  9. kubeadm init --config kubeadm.conf --ignore-preflight-errors=all

初始化完成后,记住最后输出的kebeadm join命令,其他节点加入时需要使用

  1. kubeadm join 192.168.6.20:6443 --token o7dko2.n75ix5kucj6okqwx \
  2. --discovery-token-ca-cert-hash sha256:9dc850d6699c8991ae5c543993945f49ad5358733a2ceedadaea3360ed70fb30

拷贝kebectl使用的连接k8s认证文件到默认路径:

  1. mkdir -p $HOME/.kube
  2. sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  3. sudo chown $(id -u):$(id -g) $HOME/.kube/config

查看工作节点:

  1. kubectl get nodes
  2. NAME STATUS ROLES AGE VERSION
  3. k8s-master1 NotReady control-plane,master 2m3s v1.21.0
  • 注:由于还没有部署网络插件,所以节点会显示为准备NotReady状态
  • 参考资料:

https://kubernetes.io/zh/docs/reference/setup-tools/kubeadm/kubeadm-init/#config-file

https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#initializing-your-control-plane-node

4、部署kubernetes node 【node节点】

在node节点上执行(192.168.6.21/22)执行

向集群添加新节点,执行在kubeadm init输出的kubeadm join命令

  1. kubeadm join 192.168.6.20:6443 --token o7dko2.n75ix5kucj6okqwx \
  2. --discovery-token-ca-cert-hash sha256:9dc850d6699c8991ae5c543993945f49ad5358733a2ceedadaea3360ed70fb30
  • 注:默认token有效期是24小时,当过期之后,该token将不可用;这时需要创建新的token:
  1. kubeadm token create --print-join-command

5、部署网络插件(CNI)

Calico是一个纯三层的数据中心网络方案,是目前Kubernetes主流的网络方案。

下载Calico的YUM文件:

  1. wget https://docs.projectcalico.org/manifests/calico.yaml

下载完成后还需要修改里面定义内容:

  • pod网络(CALICO_IPV4POOL_CIDR),与前面<font style="color:#F5222D;">kubeadm init</font><font style="color:#F5222D;">--pod-network-cidr</font>指定一样
  • 关闭ipip模式和修改typha_service_name修改replicas
    calico网络,默认是ipip模式(在每台node主机创建一个tunl0网口,这个隧道链接所有的node容器网络,官网推荐不同的ip网段适合,比如aws的不同区域主机)
修改成BGP模式,它会以daemonset方式安装在所有node主机,每台主机启动一个bird(BGPclient),它会将calico网络内的所有node分配的ip段告知集群内的主机,并通过本机的网卡eth0或者ens33转发数据
  • 注:下面这里我们暂时只修改最后一步,pod网络(CALICO_IPV4POOL_CIDR
  1. # 关闭ipip模式
  2. - name: CALICO_IPV4POOL_IPIP
  3. value: "off"
  4. # 修改typha_service_name
  5. typha_service_name: "calico-typha"
  6. # 修改
  7. replicas: 1
  8. revisionHistoryLimit: 2
  9. # 修改pod的网段CALICO_IPV4POOL_CIDR
  10. - name: CALICO_IPV4POOL_CIDR
  11. value: "10.244.0.0/16"

修改完成之后部署:

  1. kubectl apply -f calico.yaml
  2. kubectl get pods -n kube-system
  3. # Calico Pod都为RUNNING之后,所有节点也会进入ready状态

问题处理

5.1 CoreDNS问题处理:

  1. kubectl get pods -n kube-system
  2. NAME READY STATUS RESTARTS AGE
  3. calico-kube-controllers-8db96c76-z7h5p 1/1 Running 0 16m
  4. calico-node-pshdd 1/1 Running 0 16m
  5. calico-node-vjwlg 1/1 Running 0 16m
  6. coredns-545d6fc579-5hd9x 0/1 ImagePullBackOff 0 16m
  7. coredns-545d6fc579-wdbsz 0/1 ImagePullBackOff 0 16m
  • 可以通过kubectl describe pod/coredns-545d6fc579-5hd9x -n kube-system进行查看,一般是镜像拉取问题

所有节点执行如下:

  1. docker pull registry.aliyuncs.com/google_containers/coredns:1.8.0
  2. docker tag registry.aliyuncs.com/google_containers/coredns:1.8.0 registry.aliyuncs.com/google_containers/coredns/coredns:v1.8.0
  • 过一会儿,CoreDNS Pod会自动恢复正常。
注:以后所有yaml文件都只在Master节点执行。 参考资料:

https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#pod-network

5.2 某些Calico Pod无法启动

报错如下:

  1. Readiness probe failed: caliconode is not ready: BIRD is not ready: BGP not established with

原因:在calico.yaml文件中,IP_AUTODETECTION_METHOD 配置项默认为first-found,这种模式中calico会使用第一获取到的有效网卡,虽然会排除docker网络,localhost啥的,但是在复杂网络环境下还是有出错的可能。在这次异常中主机上的calico选择了一个vbr网卡。

提供两种解决方案,第一种机器重启后依然生效,解决方案是修改calico.yaml中 IP_AUTODETECTION_METHOD 的默认值,第二种机器重启后需要重新配置,解决方案是使用calicoctl命令。
calico.yaml 文件添加以下二行:
  1. - name: IP_AUTODETECTION_METHOD
  2. value: "interface=ens.*" # ens 根据实际网卡开头配置,支持正则表达式

上下文如下:

  1. # Cluster type to identify the deployment type
  2. - name: CLUSTER_TYPE
  3. value: "k8s,bgp"
  4. - name: IP_AUTODETECTION_METHOD
  5. value: "interface=ens.*" # ens 根据实际网卡开头配置,支持正则表达式
  6. # Auto-detect the BGP IP address.
  7. - name: IP
  8. value: "autodetect"
  9. # Enable IPIP
  10. - name: CALICO_IPV4POOL_IPIP
  11. value: "Always"
  12. # Enable or Disable VXLAN on the default IP pool.
  13. - name: CALICO_IPV4POOL_VXLAN
  14. value: "Never"

更新部署并重启服务

  1. kubectl apply -f calico.yaml

6、测试kubernetes集群

集群中创建一个nginx pod,验证是否正常运行

  1. kubectl create deployment nginx --image=nginx
  2. kubectl expose deployment nginx --port=80 --type=NodePort
  3. kubectl get pod,svc
  1. 访问地址:http://NodeIP:Port

7、部署Dashboard

Dashboard是官方提供的一个UI,可用于基本管理K8s资源。
  1. wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.3/aio/deploy/recommended.yaml
默认Dashboard只能集群内部访问,修改Service为NodePort类型,暴露到外部:
  1. vi recommended.yaml
  2. ...
  3. kind: Service
  4. apiVersion: v1
  5. metadata:
  6. labels:
  7. k8s-app: kubernetes-dashboard
  8. name: kubernetes-dashboard
  9. namespace: kubernetes-dashboard
  10. spec:
  11. ports:
  12. - port: 443
  13. targetPort: 8443
  14. nodePort: 30001
  15. selector:
  16. k8s-app: kubernetes-dashboard
  17. type: NodePort
  18. ...
  19. kubectl apply -f recommended.yaml
  20. kubectl get pods -n kubernetes-dashboard
  1. <font style="color:black;">访问地址:</font>[https://NodeIP:30001](https://NodeIP:30001)

创建service account 并绑定到默认的cluster-admin管理员集群角色:

  1. # 创建用户
  2. $ kubectl create serviceaccount dashboard-admin -n kube-system
  3. # 用户授权
  4. $ kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
  5. # 获取用户Token
  6. $ kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')

注:使用输出的token登陆dashboard

8、切换容器引擎为Containerd

参考资料:https://kubernetes.io/zh/docs/setup/production-environment/container-runtimes/#containerd ### 8.1 配置先决条件 shell # 检查内核模块如果没有则手动添加 lsmod | grep overlay lsmod | grep br_netfilter cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf overlay br_netfilter EOF sudo modprobe overlay sudo modprobe br_netfilter # 检查内核参数,如果没有需要手动添加 sysctl -a | grep bridge sysctl -a | grep ip_forward # 设置必需的 sysctl 参数,这些参数在重新启动后仍然存在。 cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 net.bridge.bridge-nf-call-ip6tables = 1 EOF # Apply sysctl params without reboot sudo sysctl --system ### 8.2 安装Containerd shell yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo yum install -y containerd.io mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml systemctl restart containerd ### 8.3 修改配置文件 + pause 镜像设置过阿里云镜像仓库地址 + cgroups 驱动设置为systemd + 拉取Docker Hub 镜像配置加速地址设置为阿里云镜像仓库地址 shell vi /etc/containerd/config.toml [plugins."io.containerd.grpc.v1.cri"] sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.2" ... [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] SystemdCgroup = true ... [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] endpoint = ["https://b9pmyelo.mirror.aliyuncs.com"] systemctl restart containerd + 授权访问私有镜像仓库 plain # 修改沙箱镜像 restrict_oom_score_adj = false #修改沙箱镜像为私有仓库的 sandbox_image = "repos-yltest-mgmt.cloud.test/kubesphere/pause:3.2" selinux_category_range = 1024 .... [plugins."io.containerd.grpc.v1.cri".registry.configs] # 内部私有仓库认证信息 [plugins."io.containerd.grpc.v1.cri".registry.configs."repos-yltest-mgmt.cloud.test"] [plugins."io.containerd.grpc.v1.cri".registry.configs."repos-yltest-mgmt.cloud.test".tls] insecure_skip_verify = true [plugins."io.containerd.grpc.v1.cri".registry.configs."repos-yltest-mgmt.cloud.test".auth] username = "admin" # 在harbor里单独创建的用户,授权访问指定项目 password = "xxxxx" [plugins."io.containerd.grpc.v1.cri".registry.configs."repos.cloud.test"] [plugins."io.containerd.grpc.v1.cri".registry.configs."repos.cloud.test".tls] insecure_skip_verify = true [plugins."io.containerd.grpc.v1.cri".registry.configs."repos.cloud.test".auth] username = "admin" # 在harbor里单独创建的用户,授权访问指定项目 password = "xxxxx" [plugins."io.containerd.grpc.v1.cri".registry.headers] 二进制安装contained,并加入k8s.docx ### 8.4 配置kubelet使用Containerd shell vi /etc/sysconfig/kubelet KUBELET_EXTRA_ARGS=--container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock --cgroup-driver=systemd systemctl restart kubelet ### 8.5 验证 shell kubectl get node -o wide k8s-node1 xxx containerd://1.4.4 ### 8.6 容器管理工具 Containerd提供了ctrl命令行工具管理容器,但功能比较简单,所以一般会用crictl工具验查和调试容器。 项目地址:https://github.com/kubernetes-sigs/cri-tools/ 设置crictl连接containerd:
  1. vi /etc/crictl.yaml
  2. runtime-endpoint: unix:///run/containerd/containerd.sock
  3. image-endpoint: unix:///run/containerd/containerd.sock
  4. timeout: 10
  5. debug: false

docker和crictl命令对照表:

镜像相关功能

镜像相关功能 Docker Containerd
显示本地镜像列表 docker images crictl images
下载镜像 docker pull crictl pull
上传镜像 docker push 例如buildk
删除本地镜像 docker rmi crictl rmi
查看镜像详情 docker inspect IMAGE-ID crictl inspecti IMAGE-ID

容器相关功能

容器相关功能 Docker Containerd
显示容器列表 docker ps crictl ps
创建容器 docker create crictl create
启动容器 docker start crictl start
停止容器 docker stop crictl stop
删除容器 docker rm crictl rm
查看容器详情 docker inspect crictl inspect
attach docker attach crictl attach
exec docker exec crictl exec
logs docker logs crictl logs
stats docker stats crictl stats

pod相关功能

POD**相关功能** Docker Containerd
显示 POD 列表 crictl pods
查看 POD 详情 crictl inspectp
运行 POD crictl runp
停止 POD crictl stopp