Kubernetes初识

1 K8s基本概念

官网:https://kubernetes.io/

Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态,其服务、支持和工具的使用范围相当广泛。Kubernetes 这个名字源于希腊语,意为“舵手”或“飞行员”。k8s 这个缩写是因为 k 和 s 之间有八个字符的关系。

1.1 核心组件概念

1.1.1 Container-容器

每个运行的容器都是可重复的; 包含依赖环境在内的标准,意味着无论你在哪里运行它都会得到相同的行为。容器将应用程序从底层的主机设施中解耦。 这使得在不同的云或 OS 环境中部署更加容易。Kubernetes 集群中的每个节点都会运行容器, 这些容器构成分配给该节点的 Pod。也就是Docker通过Image创建的Container。

1.1.2 Pod

Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。其中包含一个或多个Container。

下面是一个 Pod 示例,它由一个运行镜像 nginx:1.14.2 的容器组成。

1
2
3
4
5
6
7
8
9
10
11
#simple-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80

要创建上面显示的 Pod,请运行以下命令:

1
kubectl apply -f simple-pod.yaml

1.1.3 ReplicaSet

ReplicaSet 的目的是维护一组在任何时候都处于运行状态的 Pod 副本的稳定集合。 因此,它通常用来保证给定数量的、完全相同的 Pod 的可用性。

ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行。 然而,Deployment 是一个更高级的概念,它管理 ReplicaSet,并向 Pod 提供声明式的更新以及许多其他有用的功能。 因此,我们建议使用 Deployment 而不是直接使用 ReplicaSet, 除非你需要自定义更新业务流程或根本不需要更新。这实际上意味着,可能永远不需要操作 ReplicaSet 对象:而是使用 Deployment。

1.1.4 Deployment

一个 Deployment 为 PodReplicaSet 提供声明式的更新能力。

1.1.5 Label-标签

标签(Labels) 是附加到 Kubernetes 对象(比如 Pod)上的键值对。 标签旨在用于指定对用户有意义且相关的对象的标识属性,但不直接对核心系统有语义含义。 标签可以用于组织和选择对象的子集。标签可以在创建时附加到对象,随后可以随时添加和修改。 每个对象都可以定义一组键/值标签。每个键对于给定对象必须是唯一的。标签能够支持高效的查询和监听操作。

1.1.6 Service-服务

Kubernetes 中 Service 是 将运行在一个或一组 Pod 上的网络应用程序公开为网络服务的方法。具有相同标签Label的pod的集合。

1.1.7 Node-节点

Kubernetes 通过将容器放入在节点(Node)上运行的 Pod 中来执行你的工作。节点可以是一个虚拟机或者物理机器,取决于所在的集群配置。

1.1.8 Node Cluster

1.2 K8s架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
01-总得要有一个操作集群的客户端,也就是和集群打交道
kubectl
02-请求肯定是到达Master Node,然后再分配给Worker Node创建Pod之类的
关键是命令通过kubectl过来之后,需要认证授权
03-请求过来之后,Master Node中谁来接收?
APIServer
04-API收到请求之后,接下来调用哪个Worker Node创建Pod,Container之类的,得要有调度策略
Scheduler
[https://kubernetes.io/docs/concepts/scheduling/kube-scheduler/]
05-Scheduler通过不同的策略,真正要分发请求到不同的Worker Node上创建内容,具体谁负责?
Controller Manager
06-Worker Node接收到创建请求之后,具体谁来负责
Kubelet服务,最终Kubelet会调用Docker Engine,创建对应的容器[这边是不是也反应出一点,在Node上需要有Docker Engine,不然怎么创建维护容器?]
07-会不会涉及到域名解析的问题?
DNS
08-是否需要有监控面板能够监测整个集群的状态?
Dashboard
09-集群中节点的数据如何保存?分布式存储
ETCD
10-至于像容器的持久化存储,网络等可以先类比一下Docker中的内容

2 K8s安装

2.1 K8s的常见安装方式

  1. 最难的方式,需要自己手动安装搭建K8s架构中的各个组件

https://github.com/kelseyhightower

  1. 最简单的方式,在线体验

https://labs.play-with-k8s.com/

  1. 第三方服务:阿里ACK,腾讯TKE

阿里ACK:https://www.aliyun.com/product/kubernetes

腾讯TKE:https://cloud.tencent.com/product/tke

  1. minikube

https://minikube.sigs.k8s.io/docs/start/

  1. kubeadm

https://github.com/kubernetes/kubeadm

2.2 kubeadm搭建K8s集群

2.2.1 版本选择

1
2
3
4
centos7
Docker Community: 20.10.7
K8s Version: v1.23.14
Calico Version: v3.20

2.2.2 准备centos机器

配置要求:每台机器至少2C2G,不然运行不起来

1
2
3
192.168.0.51 master
192.168.0.52 worker01
192.168.0.53 worker02

2.2.3 安装Docker

3台机器

安装步骤查看docker专题

2.2.4 安装依赖和更新

3台机器

1
2
yum -y update
yum install -y conntrack ipvsadm ipset jq sysstat curl iptables libseccomp

2.2.5 修改hosts文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#1.master
sudo hostnamectl set-hostname m
vi /etc/hosts
192.168.0.51 m
192.168.0.52 w1
192.168.0.53 w2

#2.2台worker
sudo hostnamectl set-hostname w1/w2
vi /etc/hosts
192.168.0.51 m
192.168.0.52 w1
192.168.0.53 w2

#3.彼此ping测试一下

2.2.6 系统基础配置

3台机器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# (1)关闭防火墙
systemctl stop firewalld && systemctl disable firewalld

# (2)关闭selinux
#【SELinux 全称 Security Enhanced Linux (安全强化 Linux),是 MAC (Mandatory Access Control,强制访问控制系统)的一个实现,目的在于明确的指明某个进程可以访问哪些资源(文件、网络端口等)。】
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

# (3)关闭swap
#【在Linux下,SWAP的作用类似Windows系统下的“虚拟内存”。当物理内存不足时,拿出部分硬盘空间当SWAP分区(虚拟成内存)使用,从而解决内存容量不足的情况。】
swapoff -a
sed -i '/swap/s/^\(.*\)$/#\1/g' /etc/fstab

# (4)配置iptables的ACCEPT规则
iptables -F && iptables -X && iptables -F -t nat && iptables -X -t nat && iptables -P FORWARD ACCEPT

# (5)设置系统参数
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system

2.2.7 配置K8s的yum源

3台机器

1
2
3
4
5
6
7
8
9
10
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

2.2.8 安装kubeadm、kubectl和kubelet

3台机器

1
2
3
4
#(1)列出可以安装的版本
yum list kubeadm --showduplicates | sort -r
#(2)安装kubeadm、kubectl和kubelet
yum install -y kubeadm-1.23.14 kubelet-1.23.14 kubectl-1.23.14

2.2.9 设置Docker与K8s为同一个cgroup

3台机器

(1)Docker

1
2
3
4
5
6
# docker
vi /etc/docker/daemon.json
# 添加这行
"exec-opts": ["native.cgroupdriver=systemd"],
# 重启docker
systemctl restart docker

(2)K8s

1
2
3
4
# kubelet
sed -i "s/cgroup-driver=systemd/cgroup-driver=cgroupfs/g" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
# 重启kubelet
systemctl restart kubelet && systemctl enable kubelet

2.2.10 准备安装K8s组件需要的image

3台机器

1
2
3
4
5
6
7
8
9
kubeadm config images list

k8s.gcr.io/kube-apiserver:v1.23.14
k8s.gcr.io/kube-controller-manager:v1.23.14
k8s.gcr.io/kube-scheduler:v1.23.14
k8s.gcr.io/kube-proxy:v1.23.14
k8s.gcr.io/pause:3.6
k8s.gcr.io/etcd:3.5.5-0
k8s.gcr.io/coredns/coredns:v1.8.6

下载镜像需要科学上网,可以通过香港服务器下载后再上传到自己的镜像仓库中使用。

拉取镜像的sh:kubeadm-pull-image.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/bash

set -e

KUBE_VERSION=v1.23.14
KUBE_PAUSE_VERSION=3.6
ETCD_VERSION=3.5.5-0

ALIYUN_URL=registry.cn-hangzhou.aliyuncs.com/jack-kubernetes
GCR_URL=k8s.gcr.io

images=(kube-proxy:${KUBE_VERSION}
kube-scheduler:${KUBE_VERSION}
kube-controller-manager:${KUBE_VERSION}
kube-apiserver:${KUBE_VERSION}
pause:${KUBE_PAUSE_VERSION}
etcd:${ETCD_VERSION}
)

for imageName in ${images[@]} ; do
docker pull $ALIYUN_URL/$imageName
docker tag $ALIYUN_URL/$imageName $GCR_URL/$imageName
docker rmi $ALIYUN_URL/$imageName
done
1
2
3
docker pull registry.cn-hangzhou.aliyuncs.com/jack-kubernetes/coredns:v1.8.6
docker tag registry.cn-hangzhou.aliyuncs.com/jack-kubernetes/coredns:v1.8.6 k8s.gcr.io/coredns/coredns:v1.8.6
docker rmi registry.cn-hangzhou.aliyuncs.com/jack-kubernetes/coredns:v1.8.6

2.2.11 搭建Master

Master Node

(1)初始化Master

1
2
3
# --pod-network-cidr可以随意设置,推荐10.**.**.**开头,用于pod之间通信
kubeadm init --kubernetes-version=1.23.14 --apiserver-advertiseaddress=192.168.0.51 --pod-network-cidr=10.244.0.0/16
#记录下初始化过程中重要的日志信息

(2)记录下join的内容

1
kubeadm join 192.168.0.51:6443 --token bi2z4y.nmwqwaz5e5scqhb3 \ --discovery-token-ca-cert-hash sha256:5791deaa7119c6536cd4869ea9a152b00ae4b70b1aa19750137a077e4c6afed0

(3)根据日志提示进行如下操作

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

(4)查看cluster-info和健康检查

1
2
kubectl cluster-info
curl -k https://localhost:6443/healthz

(5)查看系统Pod

1
kubectl get pods -n kube-system

(6)kube init流程

1
2
3
4
5
6
7
8
9
10
11
12
13
# 进行一系列检查,以确定这台机器可以部署kubernetes
# 生成kubernetes对外提供服务所需要的各种证书可对应目录
ls /etc/kubernetes/pki/*
# 为其他组件生成访问kube-ApiServer所需的配置文件
ls /etc/kubernetes/
# 生成master节点需要的Pod文件。
ls /etc/kubernetes/manifests/*.yaml
# 一旦这些 YAML 文件出现在被 kubelet 监视的/etc/kubernetes/manifests/目录下,kubelet就
会自动创建这些yaml文件定义的pod,即master组件的容器。
# master容器启动后,kubeadm会通过检查localhost:6443/healthz这个master组件的健康状态检查URL,等待master组件完全运行起来
# 为集群生成一个bootstrap token
# 将ca.crt等master节点的重要信息,通过ConfigMap的方式保存在etcd中,工后续部署node节点使用
# 最后一步是安装默认插件。kubernetes默认kube-proxy和DNS两个插件是必须安装的

(7)安装calico网络插件

1
2
3
4
5
6
7
8
9
10
11
12
13
# 选择网络插件
https://kubernetes.io/docs/concepts/cluster-administration/addons/
# calico网络插件
https://projectcalico.docs.tigera.io/getting-started/kubernetes/
# 提前拉取镜像
docker pull docker.io/calico/kube-controllers:v3.20.3
docker pull docker.io/calico/pod2daemon-flexvol:v3.20.3
docker pull docker.io/calico/node:v3.20.3
docker pull docker.io/calico/cni:v3.20.3
# 安装calico:v3.20
kubectl apply -f https://docs.projectcalico.org/v3.20/manifests/calico.yaml
# 查看calico是否安装成功
watch kubectl get pods --all-namespaces

2.2.12 搭建Worker Node

(1)查看node状态

1
kubectl get nodes

(2)在2台worker node上执行

1
kubeadm join 192.168.0.51:6443 --token bi2z4y.nmwqwaz5e5scqhb3 \ --discovery-token-ca-cert-hash sha256:5791deaa7119c6536cd4869ea9a152b00ae4b70b1aa19750137a077e4c6afed0

(3)查看node状态

1
kubectl get nodes -w

2.2.13 K8s搭建之后的常见问题

  1. Node NotReady
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 问题描述
kubectl get nodes
NAME STATUS ROLES
k8s-master Ready control-plane,master
k8s-worker01 NotReady <none>
k8s-worker02 NotReady <none>
# 问题排查思路
在NotReady的node上执行:journalctl -f -u kubelet
查看其出错可能的原因:
(1)kubelet服务没有设置为开机启动:systemctl restart kubelet && systemctl enable kubelet
(2)网络环境发生了变化
(3)机器资源不足
...
#如果找不到问题,可以使用reset命令重新搭建
  1. Worker如何使用kubectl
1
2
3
4
5
6
# 问题描述,在w1节点上通过kubectl get pods查看资源,发现报错
The connection to the server localhost:8080 was refused - did you specify the right host or port?
# 解决方案
需要在worker节点上添加可以操作集群的权限,具体设置如下:
切换到master上,cd ~ ---> cat .kube/config --->复制内容
切换到worker02上 cd ~ ---> 新建文件 .kube/config --->粘贴内容
  1. token忘记了怎么办
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# token是用于worker节点加入master节点的凭证,默认有效期是24小时,格式如下
kubeadm join 192.168.0.51:6443 --token bi2z4y.nmwqwaz5e5scqhb3 \ --discovery-token-ca-cert-hash sha256:5791deaa7119c6536cd4869ea9a152b00ae4b70b1aa19750137a077e4c6afed0

# 查看token是否还在有效期内
kubeadm token list
[root@~]# kubeadm token list
TOKEN TTL EXPIRES USAGES
DESCRIPTION
ykv2ae.fsa5wj7rrxrm1xsd 21h 2022-12-06T06:17:45Z
authentication,signing The default bootstrap token generated by 'kubeadm init'.

# 如果在有效期内,则生成一个token-hash,和token一起组成用于join的内容
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

# 如果token已经过期了,则先生成一个新的token和token-hash,用于join的内容
kubeadm token create --print-join-command
kubeadm token list

# 默认token有效期是24小时,如果想设置有效期,则可以通过--ttl来设置,0表示永不过期
kubeadm token create --print-join-command --ttl=0

# 如果要删除token,则执行如下命令
kubeadm token delete 3nc3wu.pfn3mlgxafuut606

3 K8s初体验

https://kubernetes.io/docs/concepts/workloads/pods/

(1)定义一个名称为simple-pod.yaml文件

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80

(2)通过kubectl apply创建Pod

1
kubectl apply -f simple-pod.yaml

(3)查看Pod

1
2
3
4
5
6
7
8
9
# 查看Pod
kubectl get pods
kubectl get pods -w
# 查看pod运行详情
kubectl get pods -o wide
# 查看pod详情
kubectl describe pod nginx
# 比如pod被调度在了w2节点上,此时来到w2机器,使用docker的方式查看container的情况
docker ps

(4)删除Pod

1
kubectl delete -f simple-pod.yaml

Kubernetes初识
http://www.zivjie.cn/2023/04/29/云原生(容器化)/k8s/Kubernetes初识/
作者
Francis
发布于
2023年4月29日
许可协议