2129 lines
63 KiB
Markdown
2129 lines
63 KiB
Markdown
# 深入刨析Kubernetes
|
||
|
||
> 来源:原 mongodb 集合 `t_blog` · 整理日期:2026-08-25
|
||
> 分类 ID:`2022051619278900000000000002` · 排序:5 · 文章数:14
|
||
|
||
## 目录
|
||
|
||
1. [第2章 Docker](#第2章-docker)
|
||
2. [第3章 设计与架构](#第3章-设计与架构)
|
||
3. [kubernetes etcd安装](#kubernetes-etcd安装)
|
||
4. [第4章 kubeadm](#第4章-kubeadm)
|
||
5. [第5章 编排原理](#第5章-编排原理)
|
||
6. [第7章 网络原理](#第7章-网络原理)
|
||
7. [第6章 存储原理](#第6章-存储原理)
|
||
8. [第8章 调度与资源管理](#第8章-调度与资源管理)
|
||
9. [第10章 资源](#第10章-资源)
|
||
10. [第11章 权限控制](#第11章-权限控制)
|
||
11. [基于虚拟网卡共有网络k8s集群搭建](#基于虚拟网卡共有网络k8s集群搭建)
|
||
12. [kubernetes 二进制安装master](#kubernetes-二进制安装master)
|
||
13. [kubernetes Calico 配置](#kubernetes-calico-配置)
|
||
14. [kubernetes 二进制安装worker](#kubernetes-二进制安装worker)
|
||
|
||
---
|
||
|
||
## 1. 第2章 Docker
|
||
|
||
<sub>bid: `2022051619278900000000000003`</sub>
|
||
|
||
## kubernetes 第2章 Docker
|
||
### docker network
|
||
---
|
||
[参考1](https://baijiahao.baidu.com/s?id=1730776907492640810&wfr=spider&for=pc)
|
||
[参照2](https://blog.csdn.net/gui951753/article/details/79210535)
|
||
|
||
# show network command: bridge, host, none
|
||
docker network ls
|
||
# bridge
|
||
# host
|
||
# none
|
||
|
||
### docker 项目最核心的原理是,为带创建的用户进程
|
||
### 重新认识linux容器
|
||
---
|
||
1.Linux Namespace 的隔离能力
|
||
2.Linux Cgroups的限制能力
|
||
3.基于rootfs的文件系统
|
||
其中用到了chroot 和 pivot_root 两个系统调用切换进程目录的能力
|
||
docker 在镜像的设计中引入了layer的概念
|
||
docker镜像使用的rootfs往往由多个layer组成。
|
||
这些layer 分:
|
||
- ro+wh layer
|
||
- rw layer
|
||
- init layer
|
||
- init层是docker项目单独生成的内部层,专门存放/etc/hosts,/etc/resolv.conf等信息。用户 commit时 init层并不会提交。提交的时rw层。
|
||
|
||
### Dockerfile
|
||
---
|
||
[doc](https://docs.docker.com/engine/reference/builder/)
|
||
|
||
# Comment
|
||
INSTRUCTION arguments
|
||
|
||
FROM python:2.7-slim
|
||
|
||
WORKDIR /app
|
||
|
||
ADD . /app
|
||
|
||
RUN pip install --trusted-host pypi.python.org -r requirements.txt
|
||
|
||
EXPOSE 80
|
||
|
||
ENV NAME World
|
||
|
||
CMD ["python", "app.py"]
|
||
|
||
# dockerfile默认提供了一个隐式的ENTRYPOINT INSTRUCTION
|
||
即 /bin/sh -c
|
||
所以Docker容器的启动进程为ENTRYPOINT, 而不是CMD
|
||
而CMD命令为Dockerfile指定python app.py 为该容器进程
|
||
CMD的内容就是ENTRYPOINT 的参数
|
||
实际上在容器中运行的进程为 /bin/sh -c "python app.py"
|
||
|
||
### Linux Namespace 隔离机制
|
||
---
|
||
Linux Namespace虽然看不见摸不到,但是一个进程的Namespace信息在宿主机上是确实存在的,并且以文件的形式存在。
|
||
|
||
$ docker inspect --format '{{ .State.pid }}' 4ddf4542324
|
||
25686
|
||
此时,可以查看宿主机文件
|
||
$ls -l /proc/25686/ns
|
||
可以看出一个进程是有多个Namespace的,存放于该目录下。
|
||
这就意味着,一个进程可以选择加入某个Namespace中,这就是docker exec 原理
|
||
|
||
### docker Volume
|
||
在chroot之前,宿主机的文件目录对容器进程是可见的,我们只需要在rootfs准备好后,在执行chroot之前,把Volume指定的宿主机目录挂载到指定容器目录即可。
|
||
Volume里信息不会被docker commit提交。
|
||
|
||
---
|
||
|
||
## 2. 第3章 设计与架构
|
||
|
||
<sub>bid: `2022051809471000000000000005`</sub>
|
||
|
||
## kubernetes 第3章 设计与架构
|
||
### Kubernetes 设计与架构
|
||
---
|
||
容器实际上是由,Linux Namespace,Linux Cgroup,rootfs 这三种技术构建出来的。
|
||
不难看出一个运行中linux的容器其实可以被一分为二的:
|
||
1.挂载到/var/lib/docker/aufs/mnt上的rootfs,这一部分被称为容器镜像,是容器的静态视图。
|
||
2.一个由Namespace+Cgroups构成的隔离环境,这一部分被称为容器运行时,是容器的动态视图。
|
||
容器编排项目:compose+Swarm和Kubarnetes容器编排工具。
|
||
### Kubernetes的核心能力与项目定位
|
||
---
|
||
Kubernetes 的本质是平台的平台,即一个用来帮助用户构建上层平台的基础平台。
|
||
Pod是Kubernetes 中最基础的单元
|
||
声明式API是kubernetes最核心的设计理念,通过
|
||
|
||
### apiserver
|
||
|
||
### etcd
|
||
|
||
### cri
|
||
|
||
### kubectl
|
||
|
||
### kubelet
|
||
|
||
### proxy
|
||
|
||
###
|
||
|
||
---
|
||
|
||
## 3. kubernetes etcd安装
|
||
|
||
<sub>bid: `2022053111285300000000000018`</sub>
|
||
|
||
### 删除kubeadm 残留信息
|
||
---
|
||
|
||
yum remove -y kubelet kubeadm kubectl
|
||
|
||
rm -rf /etc/kubernetes/
|
||
rm -rf /etc/systemd/system/kubelet.service.d
|
||
rm -rf /etc/systemd/system/kubelet.service
|
||
rm -rf /usr/bin/kube*
|
||
rm -rf /etc/cni
|
||
rm -rf /opt/cni
|
||
rm -rf /var/lib/etcd
|
||
rm -rf /var/etcd
|
||
|
||
### etcd 集群安装
|
||
---
|
||
|
||
**1.1** 服务器规划
|
||
|
||
etcd-1
|
||
etcd-2
|
||
etcd-3
|
||
|
||
**1.2** 资源准备
|
||
|
||
wget https://github.com/kubernetes/kubernetes/archive/refs/tags/v1.23.8.tar.gz
|
||
|
||
从gethub源码中的go.mod可以看出,etcd的版本依赖是v3.5.0
|
||
然后我去下载etcd-v3.5.0
|
||
wget https://github.com/etcd-io/etcd/releases/download/v3.5.0/etcd-v3.5.0-linux-amd64.tar.gz
|
||
|
||
**1.3** cfssl证书生成工具准备
|
||
cfssl是一个开源的证书管理工具,使用json文件生成证书,相比openssl更方便使用。
|
||
找任意一台服务器操作,这里用Master1节点。
|
||
|
||
#创建目录存放cfssl工具
|
||
mkdir /software-cfssl
|
||
|
||
#下载相关工具
|
||
cd /software-cfssl
|
||
wget -q --timestamping https://storage.googleapis.com/kubernetes-the-hard-way/cfssl/1.4.1/linux/cfssl https://storage.googleapis.com/kubernetes-the-hard-way/cfssl/1.4.1/linux/cfssljson
|
||
|
||
cd /software-cfssl/
|
||
chmod +x *
|
||
mv cfssl cfssljson /usr/local/bin
|
||
|
||
**1.4** 自签证书颁发机构(CA)
|
||
|
||
# 创建工作目录
|
||
mkdir -p ~/TLS/{etcd,k8s}
|
||
cd ~/TLS/etcd/
|
||
|
||
# 生成自签CA配置
|
||
```bash
|
||
cat > ca-config.json << EOF
|
||
{
|
||
"signing": {
|
||
"default": {
|
||
"expiry": "87600h"
|
||
},
|
||
"profiles": {
|
||
"www": {
|
||
"expiry": "87600h",
|
||
"usages": [
|
||
"signing",
|
||
"key encipherment",
|
||
"server auth",
|
||
"client auth"
|
||
]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
EOF
|
||
```
|
||
```bash
|
||
cat > ca-csr.json << EOF
|
||
{
|
||
"CN": "etcd CA",
|
||
"key": {
|
||
"algo": "rsa",
|
||
"size": 2048
|
||
},
|
||
"names": [
|
||
{
|
||
"C": "CN",
|
||
"L": "ShangHai",
|
||
"ST": "ShangHai"
|
||
}
|
||
]
|
||
}
|
||
EOF
|
||
```
|
||
- 生成自签CA证书
|
||
```bash
|
||
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
|
||
```
|
||
- ca的有效证书查看
|
||
```bash
|
||
openssl x509 -in ca.pem -noout -text
|
||
```
|
||
|
||
**1.5** 签发etcd https证书
|
||
|
||
# 使用自签CA
|
||
cat > server-csr.json << EOF
|
||
{
|
||
"CN": "etcd",
|
||
"hosts": [
|
||
"49.233.4.79",
|
||
"43.138.55.43",
|
||
"43.138.73.106",
|
||
"10.0.16.3",
|
||
"10.0.8.13",
|
||
"127.0.0.1"
|
||
],
|
||
"key": {
|
||
"algo": "rsa",
|
||
"size": 2048
|
||
},
|
||
"names": [
|
||
{
|
||
"C": "CN",
|
||
"L": "ShangHai",
|
||
"ST": "ShangHai"
|
||
}
|
||
]
|
||
}
|
||
EOF
|
||
- 生成证书
|
||
```bash
|
||
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server
|
||
```
|
||
|
||
- 查看有效期
|
||
```bash
|
||
openssl x509 -in server.pem -noout -text
|
||
``
|
||
|
||
**1.5** 部署etcd集群
|
||
|
||
mkdir /usr/local/etcd-v3.5.0/{bin,cfg,ssl} -p
|
||
tar -xf etcd-v3.4.9-linux-amd64.tar.gz
|
||
mv etcd-v3.4.9-linux-amd64/{etcd,etcdctl} /usr/local/etcd-v3.5.0/bin/
|
||
---
|
||
# 创建etcd配置文件
|
||
cat > /usr/local/etcd-v3.5.0/conf/etcd.conf << EOF
|
||
#[Member]
|
||
ETCD_NAME="etcd-1" # 需要修改
|
||
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
|
||
ETCD_LISTEN_PEER_URLS="https://49.233.4.79:2380"
|
||
ETCD_LISTEN_CLIENT_URLS="https://49.233.4.79:2379"
|
||
|
||
#[Clustering]
|
||
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://49.233.4.79:2380"
|
||
ETCD_ADVERTISE_CLIENT_URLS="https://49.233.4.79:2379"
|
||
ETCD_INITIAL_CLUSTER="etcd-1=https://49.233.4.79:2380,etcd-2=https://43.138.55.43:2380,etcd-3=https://138.73.106:2380"
|
||
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
|
||
ETCD_INITIAL_CLUSTER_STATE="new"
|
||
# etc-1 为new,etcd-2/2为existing,网上很多文章都是直接copy不改,是不好使的
|
||
EOF
|
||
---
|
||
# systemd管理etcd
|
||
cat > /usr/lib/systemd/system/etcd.service << EOF
|
||
[Unit]
|
||
Description=Etcd Server
|
||
After=network.target
|
||
After=network-online.target
|
||
Wants=network-online.target
|
||
|
||
[Service]
|
||
Type=notify
|
||
EnvironmentFile=/usr/local/etcd-v3.5.0/conf/etcd.conf
|
||
User=root # 此处必须要指定用户,要不启动会报错
|
||
ExecStart=/usr/local/etcd-v3.5.0/bin/etcd \
|
||
--cert-file=/usr/local/etcd-v3.5.0/ssl/server.pem \
|
||
--key-file=/usr/local/etcd-v3.5.0/ssl/server-key.pem \
|
||
--peer-cert-file=/usr/local/etcd-v3.5.0/ssl/server.pem \
|
||
--peer-key-file=/usr/local/etcd-v3.5.0/ssl/server-key.pem \
|
||
--trusted-ca-file=/usr/local/etcd-v3.5.0/ssl/ca.pem \
|
||
--peer-trusted-ca-file=/usr/local/etcd-v3.5.0/ssl/ca.pem \
|
||
--logger=zap
|
||
Restart=on-failure
|
||
LimitNOFILE=65536
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
EOF
|
||
---
|
||
将master1节点所有生成的文件拷贝到节点2和节点3
|
||
xsync etcd-v3.5.0
|
||
---
|
||
修改节点2,节点3 ,etcd.conf配置文件中的节点名称和当前服务器IP:
|
||
---
|
||
启动etcd并设置开机自启
|
||
---
|
||
检查etcd集群状态
|
||
---
|
||
etcd问题排查(日志)
|
||
less /var/log/message
|
||
journalctl -u etcd
|
||
journalctl -xe
|
||
|
||
|
||
etcd 默认数据目录
|
||
/var/lib/etcd/
|
||
# 只有第一次启动时候,发生"msg":"request cluster ID mismatch"
|
||
rm -rf /usr/local/etcd-v3.5.0/data
|
||
|
||
systemctl stop etcd
|
||
systemctl start etcd
|
||
|
||
etcd 启动
|
||
etcd --config-file /usr/local/etcd-v3.5.0/conf/etcd.conf.yml
|
||
|
||
etcd 后台启动
|
||
nohup etcd --config-file /usr/local/etcd-v3.5.0/conf/etcd.conf.yml >/usr/local/etcd-v3.5.0/log/etcd.log 2>&1 &
|
||
|
||
测试
|
||
ETCDCTL_API=2 etcdctl
|
||
ETCDCTL_API=3 etcdctl
|
||
---
|
||
|
||
关于客户端和CA证书的问题,etcdctl 是 客户端,而我们签发的证书都是服务端证书,所以访问服务端时候必须把z
|
||
--cacert=/usr/local/etcd-v3.5.0/ssl/ca.pem --cert=/usr/local/etcd-v3.5.0/ssl/server.pem --key=/usr/local/etcd-v3.5.0/ssl/server-key.pem
|
||
|
||
---
|
||
|
||
## 4. 第4章 kubeadm
|
||
|
||
<sub>bid: `2022060613040400000000000019`</sub>
|
||
|
||
## kubernetes 第4章 kubeadm
|
||
### k8s 安装相关 doc
|
||
---
|
||
[apiDoc](https://kubernetes.io/docs/reference/config-api/)
|
||
[docker centos install doc](https://docs.docker.com/engine/install/centos/)
|
||
|
||
## 4.1 安装背景
|
||
---
|
||
腾讯云服务器,3台2G四核的不同网段的轻量云服务器(特价买的)。
|
||
因为轻量云服务器采用的是VPC网络,所以通过ip addr 命令可以看到并没有公网网址。
|
||
和一个网段私有网络不同,这里是需要公网ip的,所以做了一个临时的虚拟网卡:
|
||
|
||
`4.1.1` 创建临时网卡先应付:
|
||
|
||
# 每台机器都要做(临时网卡做法,永久性的暂时没测试)
|
||
ifconfig eth0:1 49.233.4.79 netmask 255.255.255.0 up
|
||
ifconfig eth0:1 43.138.55.43 netmask 255.255.255.0 up
|
||
ifconfig eth0:1 43.138.73.106 netmask 255.255.255.0 up
|
||
|
||
`4.1.2` 腾讯云有两个网络访问安全的设置:
|
||
|
||
# 添加 安全组 规则 放行所有6443 TCP端口
|
||
# 防火前 添加 规则 ,放行 node1 node2 node3 的6443 TCP网络
|
||
|
||
`4.1.3` hostname修改
|
||
|
||
# hostname 修改
|
||
hostnamectl set-hostname xx
|
||
|
||
`4.1.4` 设置3台机器的网络连接:
|
||
|
||
# 修改 /etc/hosts
|
||
vi /etc/hosts
|
||
|
||
# 将以下内容添加即可
|
||
49.233.4.79 node1
|
||
43.138.55.43 node2
|
||
43.138.73.106 node3
|
||
|
||
# ping
|
||
ping node3
|
||
|
||
`4.1.5` 将 SELinux 设置为 permissive 模式(相当于将其禁用)
|
||
|
||
sudo setenforce 0
|
||
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
|
||
|
||
`4.1.6` 关闭swap
|
||
|
||
swapoff -a
|
||
sed -ri 's/.*swap.*/#&/' /etc/fstab
|
||
|
||
`4.1.7` 允许 iptables 检查桥接流量
|
||
|
||
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
|
||
br_netfilter
|
||
EOF
|
||
|
||
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
|
||
net.bridge.bridge-nf-call-ip6tables = 1
|
||
net.bridge.bridge-nf-call-iptables = 1
|
||
EOF
|
||
|
||
sysctl --system
|
||
|
||
`4.1.8` 删除以前残留的网络设置信息
|
||
|
||
rm -rf /etc/cni/net.d/*
|
||
rm -rf /var/lib/cni/calico
|
||
systemctl restart kubelet
|
||
|
||
systemctl stop kubelet
|
||
systemctl stop docker
|
||
rm -rf /var/lib/cni/
|
||
rm -rf /var/lib/kubelet/*
|
||
rm -rf /etc/cni/
|
||
ifconfig cni0 down
|
||
ifconfig flannel.1 down
|
||
ifconfig docker0 down
|
||
iptb
|
||
ip link delete cni0
|
||
ip link delete flannel.1
|
||
systemctl start docker
|
||
systemctl start kubelet
|
||
|
||
### 4.2 kubeadm install
|
||
---
|
||
记录一次使用kubeadm安装的操作。
|
||
kubeadm:直接在宿主机上运行kubelet,然后使用容器部署其他k8s组件的妥协方式。
|
||
|
||
`4.2.1` docker install
|
||
Preflight check
|
||
拿到云服务器(centos 7.6)后,首先安装了docker
|
||
|
||
49.233.4.79
|
||
2705483506 43.138.55.43
|
||
3584667696 43.138.73.106
|
||
|
||
|
||
# 查看docker-ce的版本
|
||
yum list docker-ce --showduplicates | sort -r
|
||
# 安装docker
|
||
# yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io docker-compose-plugin
|
||
yum install docker-ce-20.10.17-3.el7 docker-ce-cli-20.10.17-3.el7 containerd.io docker-compose-plugin
|
||
|
||
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
|
||
[kubernetes]
|
||
name=Kubernetes
|
||
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
|
||
enabled=1
|
||
gpgcheck=1
|
||
repo_gpgcheck=0
|
||
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
|
||
EOF
|
||
|
||
`4.2.2` kubelet/kubectl/kubeadm download
|
||
|
||
# 指定版本号最好
|
||
yum -y install kubelet-1.23.7-0 kubeadm-1.23.7-0 kubectl-1.23.7-0
|
||
# 如果原来存在多个版本,请删除,因为默认是使用高版本的,会导致无法加入node
|
||
yum -y remove kubeadm* kubelet* kubectl*
|
||
|
||
systemctl enable kubelet.service
|
||
|
||
# 修改 docker 的cgroup
|
||
# 添加以下内容
|
||
vim /etc/docker/daemon.json
|
||
{
|
||
"exec-opts": ["native.cgroupdriver=systemd"]
|
||
}
|
||
# 重启docker
|
||
systemctl restart docker
|
||
docker info | grep Cgroup
|
||
|
||
|
||
### 4.3 kubeadm init
|
||
|
||
# 创建集群,其他默认就可以,需要指定集群公网地址和CIDR局域网网段
|
||
kubeadm init --apiserver-advertise-address 49.233.4.79 --pod-network-cidr=10.244.0.0/16
|
||
|
||
# 使集群生效,
|
||
mkdir -p $HOME/.kube
|
||
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
|
||
sudo chown $(id -u):$(id -g) $HOME/.kube/config
|
||
|
||
# token 24h 过期
|
||
kubeadm token create --print-join-command
|
||
# 查看集群master节点
|
||
kubectl describe node node1
|
||
|
||
# 查看集群pods,我们会发现,coredns 一直处于Pending状态,这是符合预期的,因为我们还没有安装集群插件
|
||
kubectl get pods -A
|
||
|
||
# 安装集群插件 flannel
|
||
# https://github.com/flannel-io/flannel/blob/master/Documentation/kube-flannel.yml
|
||
kubectl apply -f kube-flannel.yaml
|
||
|
||
# 安装集群网络插件
|
||
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
|
||
|
||
# 再查看集群pods,一定要先安装网络插件,再去添加集群节点哦。
|
||
kubectl get pods -A
|
||
|
||
# 加入worker节点
|
||
# 由于不在一个内网,集群间通讯默认走内网ip,因此需要借助公网ip,通过iptables转换
|
||
iptables -t nat -A OUTPUT -d -j DNAT --to-destination 青云内网ip
|
||
|
||
|
||
# 然后 kubeadm join 在其他node处添加进来。
|
||
kubeadm join 49.233.4.79:6443 --token xx.xxx \
|
||
--discovery-token-ca-cert-hash sha256:xxxxxxx
|
||
|
||
# 到这一步集群节点就算完事了。
|
||
|
||
### 4.4 ETCD
|
||
---
|
||
|
||
`4.4.1` etcd ca
|
||
|
||
# etcd 作为数据库 也有自己的ca,kubeadm 安装etcd时ca是存入以下路径
|
||
/etc/kubernetes/pki/etcd/
|
||
|
||
`4.4.2` etcd comman
|
||
|
||
1. 查看ETCD集群中运行的ETCD pod
|
||
kubectl get pod -n kube-system | grep etcd
|
||
2. 进入ETCD pod容器
|
||
kubectl exec -it etcd-node1 -n kube-system -- /bin/sh
|
||
3. 设置环境变量为v3
|
||
export ETCDCTL_API=3
|
||
4. 查看 member list
|
||
ETCDCTL_API=3 etcdctl \
|
||
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
|
||
--cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt \
|
||
--key=/etc/kubernetes/pki/etcd/healthcheck-client.key \
|
||
member list
|
||
check perf
|
||
4. 查看 key 需要加上cert才可以
|
||
etcdctl get /registry/pods/kube-system/kube-flannel-ds-vnhrw
|
||
5. 未查询简单化,添加别名
|
||
# 别名列表
|
||
alias -p
|
||
# 添加别名
|
||
alias cls=clear
|
||
# 删除别名
|
||
unalias 别名
|
||
alias etc="/usr/local/bin/etcdctl --endpoints=https://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"
|
||
6. 查询所有的key
|
||
etcdctl get / --prefix --keys-only
|
||
7. 查询flnanel配置
|
||
etcdctl get /registry/configmaps/kube-system/kube-flannel-cfg
|
||
ETCD_ENABLE_V2=true
|
||
ETCDCTL_API=2 etcdctl ls /coreos.com/network/subnets/
|
||
ETCDCTL_API=2 etcdctl cluster-health
|
||
ETCDCTL_API=2 etcdctl member list
|
||
ETCDCTL_API=3 etcdctl member list
|
||
ETCDCTL_API=3 etcdctl check perf
|
||
|
||
### 4.5 各种错误的解决方法。
|
||
---
|
||
# 最典型的就是版本不统一导致的安装错误
|
||
|
||
[ERROR CRI]: container runtime is not running: output: time="2022-06-13T10:26:24+08:00" level=fatal msg="unable to determine runtime API version: rpc error: code = Unavailable desc = connection error: desc = \"transport: Error while dialing dial unix /var/run/containerd/containerd.sock: connect: no such file or directory\""
|
||
详细过程如下:
|
||
|
||
这个原因吧 是一开始 直接yum -y install docker 发生的错,后来用docker-ce 就直接修复了
|
||
|
||
[ERROR KubeletVersion]: the kubelet version is higher than the control plane version. This is not a supported version skew and may lead to a malfunctional cluster. Kubelet version: "1.24.1" Control plane version: "1.23.7"
|
||
yum -y remove kubelet
|
||
yum -y install kubelet-1.23.7 kubeadm-1.23.7
|
||
|
||
kubeadm init 时候会发现被墙了。
|
||
|
||
I0613 12:39:59.679221 18038 checks.go:859] pulling: k8s.gcr.io/coredns/coredns:v1.8.6
|
||
[preflight] Some fatal errors occurred:
|
||
[ERROR ImagePull]: failed to pull image k8s.gcr.io/kube-apiserver:v1.23.7: output: Error response from daemon: Get "https://k8s.gcr.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
|
||
解决方案: https://www.cnblogs.com/lifan1998/p/14326761.html
|
||
DOCKERHUB_URL=registry.aliyuncs.com/google_containers
|
||
---
|
||
kubeadm init 时候kubelet check 出错
|
||
|
||
[kubelet-check] It seems like the kubelet isn't running or healthy.
|
||
[kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get "http://localhost:10248/healthz": dial tcp [::1]:10248: connect: connection refused.
|
||
|
||
使用 journalctl -xeu kubelet查看错误信息,基本上是docker 的cgroup和k8s的cgroup不一致导致的。
|
||
修改 docker 的cgroup
|
||
|
||
解决方法
|
||
# 添加以下内容
|
||
vim /etc/docker/daemon.json
|
||
{
|
||
"exec-opts": ["native.cgroupdriver=systemd"]
|
||
}
|
||
|
||
# 重启docker
|
||
systemctl restart docker
|
||
docker info | grep Cgroup
|
||
# 重新初始化
|
||
kubeadm reset # 先重置
|
||
|
||
|
||
### 上述master节点完成后进入,worker node安装
|
||
---
|
||
|
||
# 确保和主节点的kubeadm版本相同
|
||
yum list --showduplicates kubeadm
|
||
yum -y install kubeadm-1.23.7-0 kubelet-1.23.7-0 kubectl-1.23.7-0
|
||
systemctl enable kubelet.service
|
||
|
||
### /proc/sys/net/bridge/bridge-nf-call-iptables contents are not set to 1
|
||
错误
|
||
|
||
[ERROR FileContent–proc-sys-net-bridge-bridge-nf-call-iptables]: /proc/sys/net/bridge/bridge-nf-call-iptables contents are not set to 1
|
||
[preflight] If you know what you are doing, you can make a check non-fatal with --ignore-preflight-errors=...
|
||
|
||
解决方案
|
||
|
||
echo “1” >/proc/sys/net/bridge/bridge-nf-call-iptables
|
||
|
||
---
|
||
|
||
## 5. 第5章 编排原理
|
||
|
||
<sub>bid: `2022060717000500000000000021`</sub>
|
||
|
||
## kubernetes 第5章 编排原理
|
||
### 污点
|
||
---
|
||
`taints:污点,定义在节点上,是键值数据`
|
||
`tolerations:容忍度,定义在pod上,可以定义能容忍哪些污点`
|
||
|
||
|
||
taints:
|
||
- effect: NoSchedule 不会被调度
|
||
key: node-role.kubernetes.io/master
|
||
- effect: PreferNoSchedule 尽量不调度
|
||
key: node-role.kubernetes.io/master
|
||
- effect: NoExecute 驱逐节点
|
||
key: node-role.kubernetes.io/master
|
||
|
||
tolerations:
|
||
- key: "key"
|
||
operator: "Equal"
|
||
value: "value"
|
||
effect: "NoSchedule"
|
||
|
||
tolerations:
|
||
- key: "key"
|
||
operator: "Exists"
|
||
effect: "NoSchedule"
|
||
|
||
一个 toleration和一个 taint 相"匹配"是指它们有一样的key和effect
|
||
operator 默认是 Equal ,即value 相等才匹配
|
||
|
||
`master节点默认是有污点的可以通过以下命令查看`
|
||
|
||
kubectl describe nodes node1 | grep Taints
|
||
Taints: node-role.kubernetes.io/master:NoSchedule
|
||
该污点表示,不会被调度。
|
||
|
||
kubectl describe nodes node2 | grep Taints
|
||
Taints: <none>
|
||
|
||
`如何在master节点发布pod呢`
|
||
|
||
---
|
||
|
||
## 6. 第7章 网络原理
|
||
|
||
<sub>bid: `2022060814410000000000000024`</sub>
|
||
|
||
##
|
||
### 7.2 深入解析容器跨主机网络
|
||
---
|
||
为了解决容器跨主机通信问题,就一定要从Flannel项目说起。
|
||
Flannel项目目前提供了三种实现:
|
||
(1)VXLAN
|
||
(2)host-gw了。
|
||
(3)UDP
|
||
UDP是最早的支持的一种方式,但是,性能较差,已经弃用,但这种方式简单直接,也是最容易理解的一种容器跨主机网络实现。
|
||
Flannel会在宿主机上创建一些列路由规则,flannel0
|
||
flannel0是基于CIDR/16的,而docker0,eth0是基于CIDR/24的。并且flannel0设备类型很有意思,他是一个基于TUN设备(tunnel设备)
|
||
在linux中tunnel设备是在一种第三层(网络层)工作的virtual device。他的功能也非常简单,就是在操作系统内核和用户应用程序之间传递ip包。
|
||
当操作系统,将一个Ip包发送给一个flannel0设备之后,flannel0会把这个ip包交给创建该设备的应用程序,也就是Flannel进程,这是一个内核态到用户态的流动方向。
|
||
反之,如果Flannel进程,向flannel0设备发送了一个ip包,这个ip包会出现在 宿主机network stack 中,根据宿主机的路由表进行下一步处理。这是用户态向内核态的流动方向。
|
||
还有一个重要概念subnet子网:事实上,一台主机上的所有容器都会被分配一个CIDR/24的子网,而主机和子网的映射关系保存在k8s的分布式存储etcd当中。
|
||
|
||
// 查看keys
|
||
$ etcdctl ls /coreos.com/network/subnets
|
||
/coreos.com/network/subnets/100.96.1.0-24
|
||
/coreos.com/network/subnets/100.96.2.0-24
|
||
/coreos.com/network/subnets/100.96.3.0-24
|
||
|
||
// 获取public ip
|
||
$ etcdctl get /coreos.com/network/subnets/100.96.2.0-24
|
||
{"PublicIP": "10.168.0.3"}
|
||
|
||
以上过程的总结:
|
||
容器确定source ip和 target ip,如果他们在一个CIDR/24下,则走的直连规则,如果不是一个子网段,则会把ip包通过docker0进入到宿主机ip route表中进行匹配,然后进入到flannel0设备中,flannel0 通过tunnel 把ip包转给flannel1d进程,然后通过etcd查询target的共有ip,并将ip包发出。
|
||
当然,采用UDP得以实现的原因是,每台宿主机flannelid都监听着一个8285端口。
|
||
当然这种方式,性能很差,差在tunnel设备需要三次用户态和内核态的切换,很肥资源。
|
||
这也是Flannel 后来支持VXLAN的模式成为主流的网络解决方案。
|
||
|
||
### VXLAN(virtual extensible LAN 虚拟可扩展局域网)
|
||
---
|
||
是linux本来就支持的网络虚拟化技术。
|
||
VXLAN可以在完全在内核态上实现封装和解封的工作,从而构建UDP模式相似的网络。
|
||
VXLAN是在二层网络上构建出的隧道模式,只不过对他进行封装和解封的对象是二层数据帧(ethernet frame),而且这个工作全部是在内核里完成,(因为VXLAN就是linux内核的一个模块)
|
||
但是为了解决发送时IP包并不知道MAC,所以需要维护一个ARP表
|
||
可以通过命令去查看
|
||
|
||
$ ip neigh show dev flannel.1
|
||
|
||
|
||
### 7.3 kubernetes网络模型与CNI网络插件
|
||
---
|
||
7.2的流程,是k8s对容器网络的处理方法。只不过k8s是通过一个叫做CNI的接口维护了一个单独的网桥来代替docker0.默认的设备名称cni0.
|
||
具体内容就不细说了,
|
||
### 7.4 解读kubernetes 三层网络方案 host-gw
|
||
--
|
||
### 7.5 解读kubernetes 三层
|
||
--
|
||
|
||
---
|
||
|
||
## 7. 第6章 存储原理
|
||
|
||
<sub>bid: `2022060814418900000000000023`</sub>
|
||
|
||
kubernetes 第6章 存储原理
|
||
|
||
---
|
||
|
||
## 8. 第8章 调度与资源管理
|
||
|
||
<sub>bid: `2022060814420100000000000025`</sub>
|
||
|
||
## kubernetes 第8章 调度与资源管理
|
||
### 8.1 kubernetes 资源模型
|
||
---
|
||
- 可压缩资源(compressiable resources)
|
||
CPU,当他不足时,Pod只会饥饿,不会退出
|
||
- 不可压缩资源(imcompressiable resources)
|
||
内存,当他不足时,Pod会因为OOM被内核结束。
|
||
由于Pod是可以由多个Containner组成,而每个Containner都是一个进程,所以Pod整体的资源配置是由Container所有进程资源配置累加的,同时资源配置是需要配置在Container上的。
|
||
此外,k8s是允许,CPU设置成分数的,cpu=0.5或者cpu=500m这样的写法,才是k8s的内部通用表示法。
|
||
内存的单位自然就是byte,注意区分MB和Mib
|
||
**※** 1MiB 1024x1024 1Mb=1000x1000
|
||
|
||
apiVersion: v1
|
||
kind: Pod
|
||
metadata:
|
||
name: frontend
|
||
spec:
|
||
containers:
|
||
- name: db
|
||
image: mysql
|
||
env:
|
||
- name: MYSQL_ROOT_PASSWORD
|
||
value: "password"
|
||
resources:
|
||
requests:
|
||
memory: "64Mi"
|
||
cpu: "250m"
|
||
limits:
|
||
memory: "128Mi"
|
||
cpu: "500m"
|
||
- name: wp
|
||
image: wordpress
|
||
resources:
|
||
requests:
|
||
memory: "64Mi"
|
||
cpu: "250m"
|
||
limits:
|
||
memory: "128Mi"
|
||
cpu: "500m"
|
||
|
||
关于limits和requests
|
||
区别:
|
||
调度时候,kube-scheduler只会按照requests的值去计算。
|
||
而在真正设置Cgroups的时候,kubelet会按照limits去计算。
|
||
|
||
### qosclass类型
|
||
---
|
||
如果只定义了limits,那么k8s默认会将requests与limits设置一样,
|
||
qosclass字段会被k8s自动设置成Guaranteed
|
||
当Pod不满足Guaranteed,但至少有一个container设置了requests,k8s会将qosclass设置成Burstable
|
||
如果一个Pod既没有设置limits也没有设置requests,Qos的类型为BestEffort
|
||
**作用**
|
||
当宿主机资源紧张的时候,kubelet对Pod进行资源回收(Eviction)时候需要用到。具体来说,宿主机上不可压缩资源资源短缺时候,就有可能触发Eviction
|
||
目前Eviction的默认值如下:
|
||
memory.available<100Mi
|
||
nodefs.available<10%
|
||
nodefs.inodesFree<5%
|
||
imagefs.avaialble<15%
|
||
kubelet中是可以对上述Eviction进行配置的。
|
||
配置时,有两种模式Soft和Hard,
|
||
而k8s计算Eviction的阈值数据来源,是通过Cgroup读取的值和cAdsivor监控到的数据。
|
||
当宿主机的Eviction阈值达到后,会进入MemoryPressure或者DiskPressure状态,从而避免新的Pod被调度到这个宿主机。
|
||
|
||
**Eviction**
|
||
发生Eviction按照,BestEffort->Burstable(超过requests的容器)->Guaranteed
|
||
|
||
**cpuset**
|
||
我们可以通过cpuset将容器绑定到某个CPU的核上,而不是像cpushare共享cpu计算能力。这样操作系统在cpu直接的切换会大大减少。
|
||
|
||
### 8.2 kubernetes 默认调度器
|
||
---
|
||
- default scheduler
|
||
默认调度器的主要职责是,为创建出来的Pod需找一个最合适的节点。
|
||
|
||
Node selection in kube-scheduler
|
||
kube-scheduler selects a node for the pod in a 2-step operation:
|
||
1. Filtering
|
||
2. Scoring
|
||
|
||
根据算法选出,可调度的list,在根据算法从中选出最优。
|
||
Predicate算法,检查每个节点是否可用
|
||
Priority算法,给每个节点打分,得分最高的就是最终的调度结果。
|
||
而,scheduler对Pod的调度成功体现在,他的spec.nodeName字段填上调度结果的节点名字。
|
||
|
||
### 8.3 kubernetes 默认调度器调度策略
|
||
---
|
||
- 调度策略
|
||
- [doc](https://kubernetes.io/docs/reference/scheduling/policies/)
|
||
1. GeneralPredicates
|
||
|
||
2. 与Volume相关的过滤策略
|
||
NoDiskConflict检查多个Pod声明的PV是否有冲突,比如AWS EBS类型的Volume不允许被两个Pod同时使用。
|
||
MaxPDVolumeCountPredicate检查一个节点某个类型的PV是否超过一定数量。
|
||
|
||
3. 宿主机相关的过滤策略
|
||
NodeMemoryPressurePredicate
|
||
4. Pod相关的过滤策略
|
||
PodAffinityPredicate
|
||
亲密性affinity和反亲密性anti-affinity。
|
||
## 8.4 kubernetes 默认调度器优先级和抢占机制
|
||
---
|
||
Priority和Preemption解决的是Pod调度失败后该怎么办的问题。
|
||
提交一个priorityclass定义:
|
||
|
||
apiVersion: scheduling.k8s.io/v1
|
||
kind: PriorityClass
|
||
metadata:
|
||
name: high-priority
|
||
value: 1000000
|
||
globleDefault: false
|
||
description: "~~~~"
|
||
默认的Pod的priority的value是0
|
||
globleDefault是false意味着,不是默认的,需要在pod声明指定
|
||
因为scheduler中维护了一个调度队列,当Pod中priority高的就有可能提前出队列,从而更早的完成调度过程。
|
||
当一个高priority的Pod调度失败后,scheduler的抢占Preemption能力就会触发。
|
||
scheduler 在调度队列中实现了两个不同的队列:
|
||
activeQ和unschedulableQ
|
||
activeQ中的Pod都是下一次调度周期需要调度的对象
|
||
unschedulableQ存放的都是调度失败的Pod。
|
||
当一个unschedulableQ发生更新后,k8s
|
||
|
||
---
|
||
|
||
## 9. 第10章 资源
|
||
|
||
<sub>bid: `2022061515517700000000000028`</sub>
|
||
|
||
## 1. ingress来龙去脉
|
||
---
|
||
[doc](https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/)
|
||
|
||
- Ingress-nginx quick start
|
||
[quick start](https://kubernetes.github.io/ingress-nginx/deploy/#quick-start)
|
||
|
||
K8s集群对外暴露服务的方式目前只有三种:
|
||
- Loadblancer
|
||
- Nodeport
|
||
- ingress
|
||
- headerless
|
||
|
||
|
||
### ingress介绍
|
||
---
|
||
ingress由两部分组成
|
||
- ingress
|
||
指的是k8s中的一个api对象,一般用yaml配置。作用是定义请求如何转发到service的规则,可以理解为配置模板。
|
||
|
||
- ingress controller
|
||
具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发。
|
||
ingress-controller并不是k8s自带的组件,实际上ingress-controller只是一个统称,用户可以选择不 同的ingress-controller实现
|
||
目前,由k8s维护的ingress-controller只有google云的GCE与ingress-nginx两个,其他还有很多第三方维护的ingress-controller
|
||
|
||
### ingress-controller 安装
|
||
[参照](https://blog.csdn.net/weixin_38797137/article/details/124251698)
|
||
|
||
# 先现在 配置文件
|
||
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.2.0/deploy/static/provider/cloud/deploy.yaml
|
||
# 由于国内被墙,有几个镜像是下载不下来的,所以修改deploy.yaml
|
||
vi deploy.yaml
|
||
# /image 查找镜像
|
||
# 修改controller:v1.2.0
|
||
bitnami/nginx-ingress-controller:1.2.0
|
||
# 修改kube-webhook-certgen
|
||
registry.aliyuncs.com/google_containers/kube-webhook-certgen:v1.1.1
|
||
# /externalTrafficPolicy
|
||
# 修改externalTrafficPolicy = Cluster
|
||
|
||
# 最后 apply
|
||
kubectl apply -f deploy.yaml
|
||
|
||
|
||
### ingress tls 证书替换
|
||
// [可以参考 linux 下的 nginx 证书使用](https://cloud.tencent.com/document/product/400/35244)
|
||
[root@node1 ~]# kubectl create secret tls https-secret2023 --cert=/usr/local/kubernetes/secret/violin-home.cn_bundle.crt --key=/usr/local/kubernetes/secret/violin-home.cn.key -n devops
|
||
[root@node1 ~]# kubectl get secret -A
|
||
[root@node1 ~]# kubectl edit ingress violin-ingress -n devops
|
||
|
||
## 2. Service
|
||
---
|
||
[doc](https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/)
|
||
|
||
|
||
[root@node1 ~]# kubectl get svc -A
|
||
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||
default kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 2d21h
|
||
kube-system kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 2d21h
|
||
|
||
`先了解以下参与k8s网络的角色`
|
||
|
||
- kube-dns
|
||
- kube-proxy
|
||
- kube-flannel-ds
|
||
- coredns
|
||
- cni0
|
||
- controller
|
||
|
||
---
|
||
|
||
## 10. 第11章 权限控制
|
||
|
||
<sub>bid: `2022061710512100000000000001`</sub>
|
||
|
||
## RBAC规则
|
||
---
|
||
### 概念
|
||
RBAC模型(Role-Based Access Control:基于角色的访问控制)
|
||
在RBAC模型里面,有3个基础组成部分,分别是:用户、角色和权限。
|
||
- User(用户):每个用户都有唯一的UID识别,并被授予不同的角色
|
||
- Role(角色):不同角色具有不同的权限
|
||
- Permission(权限):访问权限
|
||
|
||
|
||
# user -> role <- Permission
|
||
张三 管理员 增删改查
|
||
李四 普通用户 查
|
||
王五 普通用户 查
|
||
|
||
设置角色,然后对角色进行权限设置,然后将用户和角色关联即可。
|
||
用户和权限没有必然关系,是通过角色去控制的
|
||
### kubernetes 中的RBAC
|
||
RBAC规则包含ServiceAccount、ClusterRole、ClusterRoleBinding三类YAML文件,即三种对象
|
||
|
||
- **Service Account**
|
||
是面向命名空间的:
|
||
|
||
apiVersion: v1
|
||
kind: ServiceAccount
|
||
metadata:
|
||
name: beckend-serviceaccount
|
||
namespace: kube-users
|
||
|
||
- **ClusterRole**
|
||
是面向整个集群所有命名空间的
|
||
ClusterRole的一条规则由apiGroups、resources、verbs共同组成
|
||
ClusterRole 用来描述 一个角色和他所拥有的权限
|
||
|
||
apiVersion: rbac.authorization.k8s.io/v1
|
||
kind: ClusterRole
|
||
metadata:
|
||
name: namespace-readonly
|
||
rules:
|
||
- apiGroups:
|
||
- ""
|
||
resources:
|
||
- namespaces
|
||
verbs:
|
||
- get
|
||
- list
|
||
- watch
|
||
- apiGroups:
|
||
- metrics.k8s.io
|
||
resources:
|
||
- pods
|
||
verbs:
|
||
- get
|
||
- list
|
||
- watch
|
||
|
||
- ClusterRoleBinding
|
||
是面向整个集群所有命名空间的
|
||
ClusterRoleBinding中subjects是访问API的主体
|
||
subjects包含users、groups、service accounts三种类型
|
||
我们使用的是ServiceAccount类型
|
||
ClusterRoleBinding 描述的是将 ServiceAccount(用户)和 ClusterRole(角色)jin'xing
|
||
|
||
|
||
apiVersion: rbac.authorization.k8s.io/v1
|
||
kind: ClusterRoleBinding
|
||
metadata:
|
||
name: namespace-readonly-sa
|
||
roleRef:
|
||
apiGroup: rbac.authorization.k8s.io
|
||
kind: ClusterRole
|
||
name: namespace-readonly
|
||
subjects:
|
||
- apiGroup: rbac.authorization.k8s.io
|
||
kind: ServiceAccount
|
||
name: system:serviceaccounts:kube-users
|
||
|
||
---
|
||
|
||
## 11. 基于虚拟网卡共有网络k8s集群搭建
|
||
|
||
<sub>bid: `2022062320127000000000000005`</sub>
|
||
|
||
### linux
|
||
---
|
||
|
||
- port set
|
||
|
||
在腾讯云控制面对相应端口进行放行
|
||
TCP 6443
|
||
UDP 8472
|
||
TCP 30000-32767
|
||
|
||
- SELinux 设置为 permissive 模式(相当于将其禁用)
|
||
|
||
sudo setenforce 0
|
||
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
|
||
|
||
- 关闭swap
|
||
|
||
# 临时关闭swap分区,当前会话生效,重启失效
|
||
swapoff -a
|
||
# 永久关闭swap分区
|
||
sed -ri 's/.*swap.*/#&/' /etc/fstab
|
||
|
||
|
||
- 所有机器都要做
|
||
|
||
echo "1" >/proc/sys/net/bridge/bridge-nf-call-iptables
|
||
echo 1 > /proc/sys/net/ipv4/ip_forward
|
||
vi /etc/sysctl.conf
|
||
net.ipv4.ip_forward = 1
|
||
|
||
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
|
||
net.bridge.bridge-nf-call-ip6tables = 1
|
||
net.bridge.bridge-nf-call-iptables = 1
|
||
EOF
|
||
|
||
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
|
||
br_netfilter
|
||
EOF
|
||
|
||
sudo sysctl --system
|
||
|
||
### 创建网卡
|
||
|
||
由于PVC网卡上是没有public ip 的,需要我们自定义网卡
|
||
# 每台机器都要做(临时网卡做法,永久性的暂时没测试)
|
||
# ifconfig eth0:1 49.233.4.79 netmask 255.255.255.0 up
|
||
# ifconfig eth0:1 43.138.55.43 netmask 255.255.255.0 up
|
||
# ifconfig eth0:1 43.138.73.106 netmask 255.255.255.0 up
|
||
|
||
ifconfig eth0:1 49.233.4.79
|
||
|
||
# 永久生效
|
||
cat > /etc/sysconfig/network-scripts/ifcfg-eth0:1 <<EOF
|
||
BOOTPROTO=static
|
||
DEVICE=eth0:1
|
||
IPADDR=<你的公网IP>
|
||
PREFIX=32
|
||
TYPE=Ethernet
|
||
USERCTL=no
|
||
ONBOOT=yes
|
||
EOF
|
||
|
||
|
||
|
||
### 版本信息
|
||
---
|
||
kubernetes, kubelet, kubectl, kubeadm version
|
||
v1.23.7
|
||
|
||
### 修改kubelet( per machine)
|
||
---
|
||
# 此文件安装kubeadm后就存在了
|
||
vim /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf
|
||
|
||
# 注意,这步很重要,如果不做,节点仍然会使用内网IP注册进集群
|
||
# 在末尾添加参数 --node-ip=公网IP
|
||
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS --node-ip=<公网IP>
|
||
|
||
### 编写启动配置文件
|
||
---
|
||
|
||
# 添加配置文件,注意替换下面的IP
|
||
cat > kubeadm-config.yaml <<EOF
|
||
apiVersion: kubeadm.k8s.io/v1beta3
|
||
kind: ClusterConfiguration
|
||
kubernetesVersion: v1.23.7
|
||
apiServer:
|
||
certSANs:
|
||
- master #请替换为hostname
|
||
- xx.xx.xx.xx #请替换为公网IP
|
||
- xx.xx.xx.xx #请替换为私网IP
|
||
- 10.96.0.1
|
||
controlPlaneEndpoint: xx.xx.xx.xx:6443 #替换为公网IP
|
||
imageRepository: registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images 已有镜像仓库,此处删除。
|
||
networking:
|
||
podSubnet: 10.244.0.0/16
|
||
serviceSubnet: 10.96.0.0/12
|
||
---
|
||
apiVersion: kubeproxy-config.k8s.io/v1alpha1
|
||
kind: KubeProxyConfiguration
|
||
featureGates:
|
||
SupportIPVSProxyMode: true
|
||
mode: ipvs
|
||
EOF
|
||
|
||
### kubeadm 创建master节点
|
||
---
|
||
|
||
kubeadm init --config=kubeadm-config.yaml
|
||
|
||
### 修改kube-apiserver参数(master,只修改注释项,其余的不要动)
|
||
---
|
||
|
||
# 修改两个信息,添加--bind-address和修改--advertise-address
|
||
vim /etc/kubernetes/manifests/kube-apiserver.yaml
|
||
|
||
spec:
|
||
containers:
|
||
- command:
|
||
- kube-apiserver
|
||
- --advertise-address=xx.xx.xx.xx # 修改为公网IP
|
||
- --bind-address=0.0.0.0 # 新增参数
|
||
- --allow-privileged=true
|
||
|
||
### 安装flannel网络插件(只在master 主节点执行)
|
||
---
|
||
|
||
# 1、下载flannel配置文件
|
||
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
|
||
修改 kube-flannel.yml 内容,如下:
|
||
|
||
|
||
net-conf.json: |
|
||
{
|
||
"Network": "10.244.0.0/16", # 这里是kubeadm-config.yaml配置的podsnetwork
|
||
"Backend": {
|
||
"Type": "vxlan"
|
||
}
|
||
}
|
||
|
||
|
||
containers:
|
||
- name: kube-flannel
|
||
image: quay.io/coreos/flannel:v0.14.0
|
||
command:
|
||
- /opt/bin/flanneld
|
||
args:
|
||
- --ip-masq
|
||
- --kube-subnet-mgr
|
||
- --public-ip=$(PUBLIC_IP) # 新增
|
||
- --iface=eth0 # 新增
|
||
resources:
|
||
requests:
|
||
cpu: "100m"
|
||
memory: "50Mi"
|
||
limits:
|
||
cpu: "100m"
|
||
memory: "50Mi"
|
||
securityContext:
|
||
privileged: false
|
||
capabilities:
|
||
add: ["NET_ADMIN", "NET_RAW"]
|
||
env:
|
||
- name: POD_NAME
|
||
valueFrom:
|
||
fieldRef:
|
||
fieldPath: metadata.name
|
||
- name: POD_NAMESPACE
|
||
valueFrom:
|
||
fieldRef:
|
||
fieldPath: metadata.namespace
|
||
- name: PUBLIC_IP #新增
|
||
valueFrom: #新增
|
||
fieldRef: #新增
|
||
fieldPath: status.podIP #新增
|
||
### 创建网络
|
||
---
|
||
|
||
kubectl apply -f kube-flannel.yml
|
||
|
||
### 将worker节点加入即可
|
||
---
|
||
|
||
### 关于分布式存储
|
||
---
|
||
|
||
- rook
|
||
|
||
customresourcedefinition.apiextensions.k8s.io/cephblockpoolradosnamespaces.ceph.rook.io created
|
||
clusterrole.rbac.authorization.k8s.io/cephfs-csi-nodeplugin created
|
||
clusterrolebinding.rbac.authorization.k8s.io/cephfs-csi-provisioner-role created
|
||
role.rbac.authorization.k8s.io/cephfs-external-provisioner-cfg created
|
||
rolebinding.rbac.authorization.k8s.io/cephfs-csi-provisioner-role-cfg created
|
||
serviceaccount/rook-ceph-cmd-reporter created
|
||
|
||
|
||
configmap/rook-ceph-operator-config created
|
||
deployment.apps/rook-ceph-operator created
|
||
|
||
---
|
||
|
||
## 12. kubernetes 二进制安装master
|
||
|
||
<sub>bid: `2022070116141100000000000006`</sub>
|
||
|
||
### 事前准备
|
||
---
|
||
|
||
如果以前有安装过, 请清理掉
|
||
|
||
ll /usr/lib/systemd/system/kube*
|
||
|
||
systemctl stop kube-apiserver
|
||
systemctl stop kube-controller-manager
|
||
systemctl stop kubelet
|
||
systemctl stop kube-proxy
|
||
systemctl stop kube-scheduler
|
||
|
||
|
||
目录准备
|
||
mkdir -p /usr/local/kubernetes/{bin,conf,ssl,logs}
|
||
|
||
### kube-apiserver 安装
|
||
---
|
||
|
||
`生成自签CA配置`
|
||
|
||
cat > ca-config.json << EOF
|
||
{
|
||
"signing": {
|
||
"default": {
|
||
"expiry": "87600h"
|
||
},
|
||
"profiles": {
|
||
"kubernetes": {
|
||
"expiry": "87600h",
|
||
"usages": [
|
||
"signing",
|
||
"key encipherment",
|
||
"server auth",
|
||
"client auth"
|
||
]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
EOF
|
||
|
||
cat > ca-csr.json << EOF
|
||
{
|
||
"CN": "kubernetes CA",
|
||
"key": {
|
||
"algo": "rsa",
|
||
"size": 2048
|
||
},
|
||
"names": [
|
||
{
|
||
"C": "CN",
|
||
"L": "ShangHai",
|
||
"ST": "ShangHai",
|
||
"O": "k8s",
|
||
"OU": "system"
|
||
}
|
||
]
|
||
}
|
||
EOF
|
||
|
||
生成CA
|
||
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
|
||
---
|
||
|
||
`给apiServer签发证书`
|
||
|
||
cat > server-csr.json << EOF
|
||
{
|
||
"CN": "kubernetes",
|
||
"hosts": [
|
||
"10.244.0.1",
|
||
"10.0.0.1",
|
||
"127.0.0.1",
|
||
"49.233.4.79",
|
||
"43.138.55.43",
|
||
"43.138.73.106",
|
||
"10.0.16.3",
|
||
"10.0.8.13",
|
||
"kubernetes",
|
||
"kubernetes.default",
|
||
"kubernetes.default.svc",
|
||
"kubernetes.default.svc.cluster",
|
||
"kubernetes.default.svc.cluster.local"
|
||
],
|
||
"key": {
|
||
"algo": "rsa",
|
||
"size": 2048
|
||
},
|
||
"names": [
|
||
{
|
||
"C": "CN",
|
||
"L": "ShangHai",
|
||
"ST": "ShangHai",
|
||
"O": "k8s",
|
||
"OU": "system"
|
||
}
|
||
]
|
||
}
|
||
EOF
|
||
|
||
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server
|
||
|
||
|
||
生成token
|
||
head -c 16 /dev/urandom | od -An -t x | tr -d ' '
|
||
cat > /usr/local/kubernetes/conf/token.csv << EOF
|
||
f41424f202b2c2e71da40ce20d32f1d2,kubelet-bootstrap,10001,"system:node-bootstrapper"
|
||
EOF
|
||
---
|
||
|
||
cat > /usr/lib/systemd/system/kube-apiserver.service << EOF
|
||
[Unit]
|
||
Description=Kubernetes API Server
|
||
Documentation=https://github.com/kubernetes/kubernetes
|
||
|
||
[Service]
|
||
EnvironmentFile=/usr/local/kubernetes/conf/kube-apiserver.conf
|
||
ExecStart=/usr/local/kubernetes/bin/kube-apiserver \$KUBE_APISERVER_OPTS
|
||
Restart=on-failure
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
EOF
|
||
---
|
||
|
||
vi kube-apiserver.conf
|
||
|
||
KUBE_APISERVER_OPTS="--logtostderr=false \
|
||
--v=2 \
|
||
--log-dir=/usr/local/kubernetes/logs \
|
||
--etcd-servers=https://49.233.4.79:2379,https://43.138.55.43:2379,https://43.138.73.106:2379 \
|
||
--bind-address=49.233.4.79 \
|
||
--secure-port=6443 \
|
||
--advertise-address=49.233.4.79 \
|
||
--allow-privileged=true \
|
||
--service-cluster-ip-range=10.0.0.0/16 \
|
||
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \
|
||
--authorization-mode=RBAC,Node \
|
||
--enable-bootstrap-token-auth=true \
|
||
--token-auth-file=/usr/local/kubernetes/conf/token.csv \
|
||
--service-node-port-range=30000-32767 \
|
||
--kubelet-client-certificate=/usr/local/kubernetes/ssl/server.pem \
|
||
--kubelet-client-key=/usr/local/kubernetes/ssl/server-key.pem \
|
||
--tls-cert-file=/usr/local/kubernetes/ssl/server.pem \
|
||
--tls-private-key-file=/usr/local/kubernetes/ssl/server-key.pem \
|
||
--client-ca-file=/usr/local/kubernetes/ssl/ca.pem \
|
||
--service-account-key-file=/usr/local/kubernetes/ssl/ca-key.pem \
|
||
--service-account-issuer=api \
|
||
--service-account-signing-key-file=/usr/local/kubernetes/ssl/server-key.pem \
|
||
--etcd-cafile=/usr/local/etcd-v3.5.0/ssl/ca.pem \
|
||
--etcd-certfile=/usr/local/etcd-v3.5.0/ssl/server.pem \
|
||
--etcd-keyfile=/usr/local/etcd-v3.5.0/ssl/server-key.pem \
|
||
--requestheader-client-ca-file=/usr/local/kubernetes/ssl/ca.pem \
|
||
--proxy-client-cert-file=/usr/local/kubernetes/ssl/server.pem \
|
||
--proxy-client-key-file=/usr/local/kubernetes/ssl/server-key.pem \
|
||
--requestheader-allowed-names=kubernetes \
|
||
--requestheader-extra-headers-prefix=X-Remote-Extra- \
|
||
--requestheader-group-headers=X-Remote-Group \
|
||
--requestheader-username-headers=X-Remote-User \
|
||
--enable-aggregator-routing=true \
|
||
--audit-log-maxage=30 \
|
||
--audit-log-maxbackup=3 \
|
||
--audit-log-maxsize=100 \
|
||
--audit-log-path=/usr/local/kubernetes/logs/k8s-audit.log"
|
||
|
||
---
|
||
|
||
# 刷新设置,并设置开机启动,查看status
|
||
systemctl daemon-reload
|
||
systemctl start kube-apiserver
|
||
systemctl enable kube-apiserver
|
||
systemctl status kube-apiserver -l
|
||
|
||
|
||
### kube-controller-manager 安装
|
||
---
|
||
`创建配置文件`
|
||
|
||
cat > /usr/local/kubernetes/conf/kube-controller-manager.conf << EOF
|
||
KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=false \\
|
||
--v=2 \\
|
||
--log-dir=/usr/local/kubernetes/logs \\
|
||
--leader-elect=true \\
|
||
--kubeconfig=/usr/local/kubernetes/conf/kube-controller-manager.kubeconfig \\
|
||
--bind-address=127.0.0.1 \\
|
||
--allocate-node-cidrs=true \\
|
||
--cluster-cidr=10.244.0.0/16 \\
|
||
--service-cluster-ip-range=10.0.0.0/16 \\
|
||
--cluster-signing-cert-file=/usr/local/kubernetes/ssl/ca.pem \\
|
||
--cluster-signing-key-file=/usr/local/kubernetes/ssl/ca-key.pem \\
|
||
--root-ca-file=/usr/local/kubernetes/ssl/ca.pem \\
|
||
--service-account-private-key-file=/usr/local/kubernetes/ssl/ca-key.pem \\
|
||
--cluster-signing-duration=87600h0m0s"
|
||
EOF
|
||
|
||
|
||
---
|
||
`生成证书`
|
||
|
||
cd /usr/local/kubernetes/ssl
|
||
cat > kube-controller-manager-csr.json << EOF
|
||
{
|
||
"CN": "system:kube-controller-manager",
|
||
"hosts": [],
|
||
"key": {
|
||
"algo": "rsa",
|
||
"size": 2048
|
||
},
|
||
"names": [
|
||
{
|
||
"C": "CN",
|
||
"L": "ShangHai",
|
||
"ST": "ShangHai",
|
||
"O": "system:masters",
|
||
"OU": "System"
|
||
}
|
||
]
|
||
}
|
||
EOF
|
||
|
||
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager
|
||
|
||
ll
|
||
|
||
`生成kubeconfig文件`
|
||
|
||
KUBE_CONFIG="/usr/local/kubernetes/conf/kube-controller-manager.kubeconfig"
|
||
KUBE_APISERVER="https://49.233.4.79:6443"
|
||
|
||
kubectl config set-cluster kubernetes \
|
||
--certificate-authority=/usr/local/kubernetes/ssl/ca.pem \
|
||
--embed-certs=true \
|
||
--server=${KUBE_APISERVER} \
|
||
--kubeconfig=${KUBE_CONFIG}
|
||
|
||
kubectl config set-credentials kube-controller-manager \
|
||
--client-certificate=/usr/local/kubernetes/ssl/kube-controller-manager.pem \
|
||
--client-key=/usr/local/kubernetes/ssl/kube-controller-manager-key.pem \
|
||
--embed-certs=true \
|
||
--kubeconfig=${KUBE_CONFIG}
|
||
|
||
kubectl config set-context default \
|
||
--cluster=kubernetes \
|
||
--user=kube-controller-manager \
|
||
--kubeconfig=${KUBE_CONFIG}
|
||
|
||
kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
|
||
|
||
ll /usr/local/kubernetes/conf
|
||
---
|
||
|
||
`systemd管理controller-manager`
|
||
|
||
cat > /usr/lib/systemd/system/kube-controller-manager.service << EOF
|
||
[Unit]
|
||
Description=Kubernetes Controller Manager
|
||
Documentation=https://github.com/kubernetes/kubernetes
|
||
|
||
[Service]
|
||
EnvironmentFile=/usr/local/kubernetes/conf/kube-controller-manager.conf
|
||
ExecStart=/usr/local/kubernetes/bin/kube-controller-manager \$KUBE_CONTROLLER_MANAGER_OPTS
|
||
Restart=on-failure
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
EOF
|
||
---
|
||
`启动并设置开机自启`
|
||
|
||
systemctl daemon-reload
|
||
systemctl start kube-controller-manager
|
||
systemctl enable kube-controller-manager
|
||
systemctl status kube-controller-manager -l
|
||
|
||
|
||
|
||
### kube-scheduler 安装
|
||
---
|
||
`创建配置文件`
|
||
|
||
cat > /usr/local/kubernetes/conf/kube-scheduler.conf << EOF
|
||
KUBE_SCHEDULER_OPTS="--logtostderr=false \\
|
||
--v=2 \\
|
||
--log-dir=/usr/local/kubernetes/logs \\
|
||
--leader-elect \\
|
||
--kubeconfig=/usr/local/kubernetes/conf/kube-scheduler.kubeconfig \\
|
||
--bind-address=127.0.0.1"
|
||
EOF
|
||
---
|
||
`生成kubeconfig文件`
|
||
|
||
cd /usr/local/kubernetes/ssl
|
||
|
||
cat > kube-scheduler-csr.json << EOF
|
||
{
|
||
"CN": "system:kube-scheduler",
|
||
"hosts": [],
|
||
"key": {
|
||
"algo": "rsa",
|
||
"size": 2048
|
||
},
|
||
"names": [
|
||
{
|
||
"C": "CN",
|
||
"L": "ShangHai",
|
||
"ST": "ShangHai",
|
||
"O": "system:masters",
|
||
"OU": "System"
|
||
}
|
||
]
|
||
}
|
||
EOF
|
||
|
||
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-scheduler-csr.json | cfssljson -bare kube-scheduler
|
||
|
||
ll
|
||
---
|
||
`生成kubeconfig文件 `
|
||
|
||
KUBE_CONFIG="/usr/local/kubernetes/conf/kube-scheduler.kubeconfig"
|
||
KUBE_APISERVER="https://49.233.4.79:6443"
|
||
|
||
kubectl config set-cluster kubernetes \
|
||
--certificate-authority=/usr/local/kubernetes/ssl/ca.pem \
|
||
--embed-certs=true \
|
||
--server=${KUBE_APISERVER} \
|
||
--kubeconfig=${KUBE_CONFIG}
|
||
|
||
kubectl config set-credentials kube-scheduler \
|
||
--client-certificate=/usr/local/kubernetes/ssl/kube-scheduler.pem \
|
||
--client-key=/usr/local/kubernetes/ssl/kube-scheduler-key.pem \
|
||
--embed-certs=true \
|
||
--kubeconfig=${KUBE_CONFIG}
|
||
|
||
kubectl config set-context default \
|
||
--cluster=kubernetes \
|
||
--user=kube-scheduler \
|
||
--kubeconfig=${KUBE_CONFIG}
|
||
|
||
kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
|
||
|
||
---
|
||
`systemd管理scheduler`
|
||
|
||
cat > /usr/lib/systemd/system/kube-scheduler.service << EOF
|
||
[Unit]
|
||
Description=Kubernetes Scheduler
|
||
Documentation=https://github.com/kubernetes/kubernetes
|
||
|
||
[Service]
|
||
EnvironmentFile=/usr/local/kubernetes/conf/kube-scheduler.conf
|
||
ExecStart=/usr/local/kubernetes/bin/kube-scheduler \$KUBE_SCHEDULER_OPTS
|
||
Restart=on-failure
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
EOF
|
||
|
||
---
|
||
`启动并设置开机启动`
|
||
|
||
systemctl daemon-reload
|
||
systemctl start kube-scheduler
|
||
systemctl enable kube-scheduler
|
||
systemctl status kube-scheduler -l
|
||
|
||
---
|
||
|
||
### kubectl 安装
|
||
---
|
||
|
||
`生成kubectl连接集群的证书`
|
||
|
||
cd /usr/local/kubernetes/ssl
|
||
cat > admin-csr.json <<EOF
|
||
{
|
||
"CN": "admin",
|
||
"hosts": [],
|
||
"key": {
|
||
"algo": "rsa",
|
||
"size": 2048
|
||
},
|
||
"names": [
|
||
{
|
||
"C": "CN",
|
||
"L": "ShangHai",
|
||
"ST": "ShangHai",
|
||
"O": "system:masters",
|
||
"OU": "System"
|
||
}
|
||
]
|
||
}
|
||
EOF
|
||
|
||
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin
|
||
ll
|
||
---
|
||
`生成kubeconfig文件`
|
||
|
||
rm -rf /root/.kube
|
||
mkdir /root/.kube
|
||
|
||
KUBE_CONFIG="/root/.kube/config"
|
||
KUBE_APISERVER="https://49.233.4.79:6443"
|
||
|
||
kubectl config set-cluster kubernetes \
|
||
--certificate-authority=/usr/local/kubernetes/ssl/ca.pem \
|
||
--embed-certs=true \
|
||
--server=${KUBE_APISERVER} \
|
||
--kubeconfig=${KUBE_CONFIG}
|
||
|
||
kubectl config set-credentials cluster-admin \
|
||
--client-certificate=/usr/local/kubernetes/ssl/admin.pem \
|
||
--client-key=/usr/local/kubernetes/ssl/admin-key.pem \
|
||
--embed-certs=true \
|
||
--kubeconfig=${KUBE_CONFIG}
|
||
|
||
kubectl config set-context default \
|
||
--cluster=kubernetes \
|
||
--user=cluster-admin \
|
||
--kubeconfig=${KUBE_CONFIG}
|
||
|
||
kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
|
||
|
||
ll
|
||
|
||
---
|
||
`通过kubectl工具查看当前集群组件状态`
|
||
|
||
[root@k8s-master1 ssl]# kubectl get cs
|
||
Warning: v1 ComponentStatus is deprecated in v1.19+
|
||
NAME STATUS MESSAGE ERROR
|
||
scheduler Healthy ok
|
||
controller-manager Healthy ok
|
||
etcd-2 Healthy {"health":"true","reason":""}
|
||
etcd-0 Healthy {"health":"true","reason":""}
|
||
etcd-1 Healthy {"health":"true","reason":""}
|
||
|
||
如上说明Master节点组件运行正常。
|
||
|
||
---
|
||
`授权kubelet-bootstrap用户允许请求证书`
|
||
|
||
kubectl create clusterrolebinding kubelet-bootstrap \
|
||
--clusterrole=system:node-bootstrapper \
|
||
--user=kubelet-bootstrap
|
||
|
||
|
||
|
||
---
|
||
|
||
### kubelet
|
||
---
|
||
`kubelet是 kubernetes 工作节点上的一个代理组件,运行在每个节点上。由于我的三台服务都是工作节点,所以也都需要装kubelet和kube-proxy`
|
||
`apiserver <-> kubelet <-> pod`
|
||
---
|
||
`创建服务`
|
||
|
||
|
||
cat > /usr/lib/systemd/system/kubelet.service << EOF
|
||
[Unit]
|
||
Description=Kubernetes Kubelet
|
||
After=docker.service
|
||
|
||
[Service]
|
||
EnvironmentFile=/usr/local/kubernetes/conf/kubelet.conf
|
||
ExecStart=/usr/local/kubernetes/bin/kubelet \$KUBELET_OPTS
|
||
Restart=on-failure
|
||
LimitNOFILE=65536
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
EOF
|
||
---
|
||
`创建服务配置文件`
|
||
|
||
cat > /usr/local/kubernetes/conf/kubelet.conf << EOF
|
||
KUBELET_OPTS="--logtostderr=false \\
|
||
--v=2 \\
|
||
--log-dir=/usr/local/kubernetes/logs \\
|
||
--network-plugin=cni \\
|
||
--hostname-override=k8s-master1 \\
|
||
--kubeconfig=/usr/local/kubernetes/conf/kubelet.kubeconfig \\
|
||
--bootstrap-kubeconfig=/usr/local/kubernetes/conf/bootstrap.kubeconfig \\
|
||
--config=/usr/local/kubernetes/conf/kubelet-config.yml \\
|
||
--cert-dir=/usr/local/kubernetes/ssl \\
|
||
--pod-infra-container-image=k8s.gcr.io/pause:3.6"
|
||
EOF
|
||
|
||
---
|
||
`创建k8s kubelet资源文件`
|
||
|
||
cat > /usr/local/kubernetes/conf/kubelet-config.yml << EOF
|
||
kind: KubeletConfiguration
|
||
apiVersion: kubelet.config.k8s.io/v1beta1
|
||
address: 0.0.0.0
|
||
port: 10250
|
||
readOnlyPort: 10255
|
||
cgroupDriver: systemd
|
||
clusterDNS:
|
||
- 10.0.0.2
|
||
clusterDomain: cluster.local
|
||
failSwapOn: false
|
||
authentication:
|
||
anonymous:
|
||
enabled: false
|
||
webhook:
|
||
cacheTTL: 2m0s
|
||
enabled: true
|
||
x509:
|
||
clientCAFile: /usr/local/kubernetes/ssl/ca.pem
|
||
authorization:
|
||
mode: Webhook
|
||
webhook:
|
||
cacheAuthorizedTTL: 5m0s
|
||
cacheUnauthorizedTTL: 30s
|
||
evictionHard:
|
||
imagefs.available: 15%
|
||
memory.available: 100Mi
|
||
nodefs.available: 10%
|
||
nodefs.inodesFree: 5%
|
||
maxOpenFiles: 1000000
|
||
maxPods: 110
|
||
EOF
|
||
|
||
---
|
||
KUBE_CONFIG="/usr/local/kubernetes/conf/bootstrap.kubeconfig"
|
||
KUBE_APISERVER="https://49.233.4.79:6443" # apiserver IP:PORT
|
||
TOKEN="f41424f202b2c2e71da40ce20d32f1d2" # 与token.csv里保持一致 /usr/local/kubernetes/conf/token.csv
|
||
|
||
# 生成 kubelet bootstrap kubeconfig 配置文件
|
||
kubectl config set-cluster kubernetes \
|
||
--certificate-authority=/usr/local/kubernetes/ssl/ca.pem \
|
||
--embed-certs=true \
|
||
--server=${KUBE_APISERVER} \
|
||
--kubeconfig=${KUBE_CONFIG}
|
||
|
||
kubectl config set-credentials "kubelet-bootstrap" \
|
||
--token=${TOKEN} \
|
||
--kubeconfig=${KUBE_CONFIG}
|
||
|
||
kubectl config set-context default \
|
||
--cluster=kubernetes \
|
||
--user="kubelet-bootstrap" \
|
||
--kubeconfig=${KUBE_CONFIG}
|
||
|
||
kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
|
||
|
||
ll
|
||
|
||
---
|
||
|
||
systemctl daemon-reload
|
||
systemctl stop kubelet
|
||
systemctl start kubelet
|
||
systemctl enable kubelet
|
||
systemctl status kubelet -l
|
||
|
||
---
|
||
|
||
kubectl get csr
|
||
|
||
kubectl certificate approve node-csr-KbHieprZUMOvTFMHGQ1RNTZEhsSlT5X6wsh2lzfUry4
|
||
certificatesigningrequest.certificates.k8s.io/node-csr-KbHieprZUMOvTFMHGQ1RNTZEhsSlT5X6wsh2lzfUry4 approved
|
||
|
||
---
|
||
|
||
`部署kube-proxy`
|
||
|
||
cat > /usr/local/kubernetes/conf/kube-proxy.conf << EOF
|
||
KUBE_PROXY_OPTS="--logtostderr=false \\
|
||
--v=2 \\
|
||
--log-dir=/usr/local/kubernetes/logs \\
|
||
--config=/usr/local/kubernetes/conf/kube-proxy-config.yml"
|
||
EOF
|
||
|
||
---
|
||
|
||
cat > /usr/local/kubernetes/conf/kube-proxy-config.yml << EOF
|
||
kind: KubeProxyConfiguration
|
||
apiVersion: kubeproxy.config.k8s.io/v1alpha1
|
||
bindAddress: 0.0.0.0
|
||
metricsBindAddress: 0.0.0.0:10249
|
||
clientConnection:
|
||
kubeconfig: /usr/local/kubernetes/conf/kube-proxy.kubeconfig
|
||
hostnameOverride: k8s-master1
|
||
clusterCIDR: 10.244.0.0/16
|
||
EOF
|
||
|
||
---
|
||
|
||
cd /usr/local/kubernetes/ssl
|
||
|
||
cat > kube-proxy-csr.json << EOF
|
||
{
|
||
"CN": "system:kube-proxy",
|
||
"hosts": [],
|
||
"key": {
|
||
"algo": "rsa",
|
||
"size": 2048
|
||
},
|
||
"names": [
|
||
{
|
||
"C": "CN",
|
||
"L": "ShangHai",
|
||
"ST": "ShangHai",
|
||
"O": "k8s",
|
||
"OU": "System"
|
||
}
|
||
]
|
||
}
|
||
EOF
|
||
|
||
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy
|
||
ll
|
||
|
||
|
||
---
|
||
|
||
`生成kube-proxy.kubeconfig文件`
|
||
|
||
KUBE_CONFIG="/usr/local/kubernetes/conf/kube-proxy.kubeconfig"
|
||
KUBE_APISERVER="https://49.233.4.79:6443"
|
||
|
||
kubectl config set-cluster kubernetes \
|
||
--certificate-authority=/usr/local/kubernetes/ssl/ca.pem \
|
||
--embed-certs=true \
|
||
--server=${KUBE_APISERVER} \
|
||
--kubeconfig=${KUBE_CONFIG}
|
||
|
||
kubectl config set-credentials kube-proxy \
|
||
--client-certificate=/usr/local/kubernetes/ssl/kube-proxy.pem \
|
||
--client-key=/usr/local/kubernetes/ssl/kube-proxy-key.pem \
|
||
--embed-certs=true \
|
||
--kubeconfig=${KUBE_CONFIG}
|
||
|
||
kubectl config set-context default \
|
||
--cluster=kubernetes \
|
||
--user=kube-proxy \
|
||
--kubeconfig=${KUBE_CONFIG}
|
||
|
||
kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
|
||
|
||
---
|
||
|
||
cat > /usr/lib/systemd/system/kube-proxy.service << EOF
|
||
[Unit]
|
||
Description=Kubernetes Proxy
|
||
After=network.target
|
||
|
||
[Service]
|
||
EnvironmentFile=/usr/local/kubernetes/conf/kube-proxy.conf
|
||
ExecStart=/usr/local/kubernetes/bin/kube-proxy \$KUBE_PROXY_OPTS
|
||
Restart=on-failure
|
||
LimitNOFILE=65536
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
EOF
|
||
|
||
---
|
||
|
||
systemctl daemon-reload
|
||
systemctl stop kube-proxy
|
||
systemctl start kube-proxy
|
||
systemctl enable kube-proxy
|
||
systemctl status kube-proxy -l
|
||
|
||
---
|
||
|
||
## 13. kubernetes Calico 配置
|
||
|
||
<sub>bid: `2022070223079600000000000007`</sub>
|
||
|
||
### 官方网站
|
||
---
|
||
该插件与kubernetes版本对应。
|
||
https://projectcalico.docs.tigera.io/archive/v3.20/getting-started/kubernetes/requirements
|
||
|
||
### 安装
|
||
---
|
||
安装文档
|
||
https://projectcalico.docs.tigera.io/archive/v3.23/getting-started/kubernetes/self-managed-onprem/onpremises#install-calico-with-kubernetes-api-datastore-50-nodes-or-less
|
||
|
||
### 填坑
|
||
---
|
||
|
||
``
|
||
|
||
rm -rf /etc/cni/net.d/*
|
||
rm -rf /var/lib/cni/calico
|
||
systemctl restart kubelet
|
||
|
||
systemctl stop kubelet
|
||
systemctl stop docker
|
||
rm -rf /var/lib/cni/
|
||
rm -rf /var/lib/kubelet/*
|
||
rm -rf
|
||
ifconfig cni0 down
|
||
ifconfig flannel.1 down
|
||
ifconfig docker0 down
|
||
iptb
|
||
ip link delete cni0
|
||
ip link delete flannel.1
|
||
systemctl start docker
|
||
systemctl start kubelet
|
||
|
||
|
||
|
||
`关于污点和容忍`
|
||
|
||
kubectl taint node k8s-master1 node.kubernetes.io/not-ready-
|
||
|
||
``
|
||
|
||
|
||
cat > apiserver-to-kubelet-rbac.yaml << EOF
|
||
apiVersion: rbac.authorization.k8s.io/v1
|
||
kind: ClusterRole
|
||
metadata:
|
||
annotations:
|
||
rbac.authorization.kubernetes.io/autoupdate: "true"
|
||
labels:
|
||
kubernetes.io/bootstrapping: rbac-defaults
|
||
name: system:kube-apiserver-to-kubelet
|
||
rules:
|
||
- apiGroups:
|
||
- ""
|
||
resources:
|
||
- nodes/proxy
|
||
- nodes/stats
|
||
- nodes/log
|
||
- nodes/spec
|
||
- nodes/metrics
|
||
- pods/log
|
||
verbs:
|
||
- "*"
|
||
---
|
||
apiVersion: rbac.authorization.k8s.io/v1
|
||
kind: ClusterRoleBinding
|
||
metadata:
|
||
name: system:kube-apiserver
|
||
namespace: ""
|
||
roleRef:
|
||
apiGroup: rbac.authorization.k8s.io
|
||
kind: ClusterRole
|
||
name: system:kube-apiserver-to-kubelet
|
||
subjects:
|
||
- apiGroup: rbac.authorization.k8s.io
|
||
kind: User
|
||
name: kubernetes
|
||
EOF
|
||
|
||
kubectl apply -f apiserver-to-kubelet-rbac.yaml
|
||
|
||
ー--
|
||
|
||
---
|
||
|
||
## 14. kubernetes 二进制安装worker
|
||
|
||
<sub>bid: `2022070314528700000000000008`</sub>
|
||
|
||
### kubelet
|
||
---
|
||
`kubelet是 kubernetes 工作节点上的一个代理组件,运行在每个节点上。由于我的三台服务都是工作节点,所以也都需要装kubelet和kube-proxy`
|
||
`apiserver <-> kubelet <-> pod`
|
||
---
|
||
`创建服务`
|
||
|
||
|
||
cat > /usr/lib/systemd/system/kubelet.service << EOF
|
||
[Unit]
|
||
Description=Kubernetes Kubelet
|
||
After=docker.service
|
||
|
||
[Service]
|
||
EnvironmentFile=/usr/local/kubernetes/conf/kubelet.conf
|
||
ExecStart=/usr/local/kubernetes/bin/kubelet \$KUBELET_OPTS
|
||
Restart=on-failure
|
||
LimitNOFILE=65536
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
EOF
|
||
---
|
||
`创建服务配置文件`
|
||
|
||
cat > /usr/local/kubernetes/conf/kubelet.conf << EOF
|
||
KUBELET_OPTS="--logtostderr=false \\
|
||
--v=2 \\
|
||
--log-dir=/usr/local/kubernetes/logs \\
|
||
--network-plugin=cni \\
|
||
--hostname-override=k8s-node3 \\
|
||
--kubeconfig=/usr/local/kubernetes/conf/kubelet.kubeconfig \\
|
||
--bootstrap-kubeconfig=/usr/local/kubernetes/conf/bootstrap.kubeconfig \\
|
||
--config=/usr/local/kubernetes/conf/kubelet-config.yml \\
|
||
--cert-dir=/usr/local/kubernetes/ssl \\
|
||
--pod-infra-container-image=k8s.gcr.io/pause:3.6"
|
||
EOF
|
||
|
||
---
|
||
`创建k8s kubelet资源文件`
|
||
|
||
cat > /usr/local/kubernetes/conf/kubelet-config.yml << EOF
|
||
kind: KubeletConfiguration
|
||
apiVersion: kubelet.config.k8s.io/v1beta1
|
||
address: 0.0.0.0
|
||
port: 10250
|
||
readOnlyPort: 10255
|
||
cgroupDriver: systemd
|
||
clusterDNS:
|
||
- 10.0.0.2
|
||
clusterDomain: cluster.local
|
||
failSwapOn: false
|
||
authentication:
|
||
anonymous:
|
||
enabled: false
|
||
webhook:
|
||
cacheTTL: 2m0s
|
||
enabled: true
|
||
x509:
|
||
clientCAFile: /usr/local/kubernetes/ssl/ca.pem
|
||
authorization:
|
||
mode: Webhook
|
||
webhook:
|
||
cacheAuthorizedTTL: 5m0s
|
||
cacheUnauthorizedTTL: 30s
|
||
evictionHard:
|
||
imagefs.available: 15%
|
||
memory.available: 100Mi
|
||
nodefs.available: 10%
|
||
nodefs.inodesFree: 5%
|
||
maxOpenFiles: 1000000
|
||
maxPods: 110
|
||
EOF
|
||
|
||
---
|
||
KUBE_CONFIG="/usr/local/kubernetes/conf/bootstrap.kubeconfig"
|
||
KUBE_APISERVER="https://49.233.4.79:6443" # apiserver IP:PORT
|
||
TOKEN="47d803a011a25fee21cc2fa434c391aa" # 与token.csv里保持一致 /opt/kubernetes/cfg/token.csv
|
||
|
||
# 生成 kubelet bootstrap kubeconfig 配置文件
|
||
kubectl config set-cluster kubernetes \
|
||
--certificate-authority=/usr/local/kubernetes/ssl/ca.pem \
|
||
--embed-certs=true \
|
||
--server=${KUBE_APISERVER} \
|
||
--kubeconfig=${KUBE_CONFIG}
|
||
|
||
kubectl config set-credentials "kubelet-bootstrap" \
|
||
--token=${TOKEN} \
|
||
--kubeconfig=${KUBE_CONFIG}
|
||
|
||
kubectl config set-context default \
|
||
--cluster=kubernetes \
|
||
--user="kubelet-bootstrap" \
|
||
--kubeconfig=${KUBE_CONFIG}
|
||
|
||
kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
|
||
|
||
---
|
||
|
||
systemctl daemon-reload
|
||
systemctl stop kubelet
|
||
systemctl start kubelet
|
||
systemctl enable kubelet
|
||
systemctl status kubelet -l
|
||
|
||
---
|