k8s学习笔记

记录自己学习 b 站视频 Kubernetes(k8s)入门到实战教程丨全新升级完整版 的笔记。

kubernetes(k8s)课程.pdf

第一部分 概述

1.1 k8s 概述和特性

1.1.1 k8s 概念

  • k8s 是谷歌在 2014 年开源的容器化集群管理系统
  • 使用 k8s 进行容器化应用部署
  • 使用 k8s 利于应用扩展
  • k8s 目标实施让部署容器化应用更加简洁和高效

1.1.2 k8s 特性

  • (1)自动装箱 基于容器对应用运行环境的资源配置要求自动部署应用容器
  • (2)自我修复(自愈能力) 当容器失败时,会对容器进行重启。当所部署的 Node 节点有问题时,会对容器进行重新部署和重新调度。当容器未通过监控检查时,会关闭此容器直到容器正常运行时,才会对外提供服务。
  • (3)水平扩展 通过简单的命令、用户 UI 界面或基于 CPU 等资源使用情况,对应用容器进行规模扩大或规模剪裁
    (3)服务发现 用户不需使用额外的服务发现机制,就能够基于Kubernetes 自身能力实现服务发现和负载均衡
    (4)滚动更新 可以根据应用的变化,对应用容器运行的应用,进行一次性或批量式更新
    (5)版本回退 可以根据应用部署情况,对应用容器运行的应用,进行历史版本即时回退
    (6)密钥和配置管理 在不需要重新构建镜像的情况下,可以部署和更新密钥和应用配置,类似热部署。
    (7)存储编排 自动实现存储系统挂载及应用,特别对有状态应用实现数据持久化非常重要。存储系统可以来自于本地目录、网络存储(NFS、Gluster、Ceph 等)、公共云存储服务
    (8)批处理 提供一次性任务,定时任务;满足批量数据处理和分析的场景

1.2 k8s 架构组件

  • Master 主控节点
    • apiserver:集群统一入口,以 restful 方式,交给 etcd 存储
    • scheduler:节点调度,选择 node 节点应用部署
    • controller-manager:处理集群中常规后台任务,一个资源对应一个控制器
    • etcd:存储系统,用于保存集群相关的数据
  • Node 工作节点
    • kubelet:master 派到 node 节点代表,管理本机容器
    • kube-proxy:提供网络代理,负载均衡等操作
      概述特性和架构组件

1.3 k8s 核心概念

  • Pod
    • 最小部署单元
    • 一组容器的集合
    • 共享网络
    • 生命周期是短暂的
  • Controller
    • 确保预期的 pod 副本数量
    • 无状态应用部署
    • 有状态应用部署
    • 确保所有的 node 运行同一个 pod
    • 一次性任务和定时任务
  • Service
    • 定义一组 pod 的访问规则
      k8s 核心概念

第二部分 集群搭建(kubeadm)

平台规划和搭建方式
目前生产部署 Kubernetes 集群主要有两种方式:

  • (1)kubeadm
    Kubeadm 是一个 K8s 部署工具,提供 kubeadm init 和 kubeadm join,用于快速部署 Kubernetes 集群。
    官方地址:https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/
  • (2)二进制包
    从 github 下载发行版的二进制包,手动部署每个组件,组成 Kubernetes 集群。
    Kubeadm 降低部署门槛,但屏蔽了很多细节,遇到问题很难排查。如果想更容易可控,推荐使用二进制包部署 Kubernetes 集群,虽然手动部署麻烦点,期间可以学习很多工作原理,也利于后期维护。

kubeadm 是官方社区推出的一个用于快速部署 kubernetes 集群的工具,这个工具能通
过两条指令完成一个 kubernetes 集群的部署:
第一、创建一个 Master 节点 kubeadm init
第二, 将 Node 节点加入到当前集群中 $ kubeadm join <Master

2.1 系统初始化

角色 IP
master 192.168.0.100
node1 192.168.0.101
node2 192.168.0.102
  1. 关闭防火墙
# 临时关闭
systemctl stop firewalld
# 永久关闭
systemctl disable firewalld
  1. 关闭 selinux
# 永久
sed -i 's/enforcing/disabled/' /etc/selinux/config
# 临时
setenforce 0
  1. 关闭 swap
# 临时
swapoff -a
# 永久
sed -ri 's/.*swap.*/#&/' /etc/fstab
  1. 主机名
hostnamectl set-hostname <hostname>
  1. 在 master 添加 hosts
cat >> /etc/hosts << EOF
192.168.0.100 master
192.168.0.101 node1
192.168.0.102 node2
EOF
  1. 将桥接的 IPv4 流量传递到 iptables 的链
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
# 生效
sysctl --system
  1. 时间同步
yum install ntpdate -y
ntpdate time.windows.com

2.2 所有节点安装Docker/kubeadm/kubelet

Kubernetes 默认 CRI(容器运行时)为 Docker,因此先安装 Docker

  1. 安装 Docker
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
yum -y install docker-ce-18.06.1.ce-3.el7
systemctl enable docker && systemctl start docker
docker --version
# docker 镜像加速
cat > /etc/docker/daemon.json << EOF
{
  "registry-mirrors": ["https://m5fsbji5.mirror.aliyuncs.com"]
}
EOF
# 重启 docker
systemctl restart docker
  1. 添加阿里云 YUM 软件源
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
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
  1. 安装 kubeadm,kubelet 和 kubectl
yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0
systemctl enable kubelet

2.3 部署 Kubernetes Master

  1. 在 192.168.1.100(Master)执行
kubeadm init \
--apiserver-advertise-address=192.168.1.100 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.18.0 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16

由于默认拉取镜像地址 k8s.gcr.io 国内无法访问,这里指定阿里云镜像仓库地址。

  1. 使用 kubectl 工具
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# 查看 node
kubectl get nodes

2.4 安装 Pod 网络插件(CNI)

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

如果下载失败,可以

  • 199.232.68.133 raw.githubusercontent.com 加到 /etc/hosts
  • 然后 wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
  • 最后 kubectl apply -f kube-flannel.yml

2.5 加入 Kubernetes Node

在 192.168.1.101 (node1) 和 192.168.1.102 (node2) 执行
向集群添加新节点,执行在 kubeadm init 输出的 kubeadm join 命令

kubeadm join 192.168.0.100:6443 --token u3ghdl.a88rxa6w56med5lc \
    --discovery-token-ca-cert-hash sha256:1c4c5b956cacf84468656154742508b464fb4a3c85c60766e00813d770e3d2fa

查看状态

kubectl get pod -n kube-system

2.6 测试 kubernetes 集群

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

# 创建 pod
kubectl create deployment nginx --image=nginx
# 暴露端口
kubectl expose deployment nginx --port=80 --type=NodePort
# 查看
kubectl get pod,svc

访问地址:http://NodeIP:Por

搭建k8s集群(kubeadm方式)

第三部分 kubernetes 集群搭建(二进制方式)

3.1 系统初始化

3.2 部署 etcd 集群

3.2.1 准备 cfssl 证书生成工具

cfssl 是一个开源的证书管理工具,使用 json 文件生成证书,相比 openssl 更方便使用。找任意一台服务器操作,这里用 Master 节点。

wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
chmod +x cfssl*
mv cfssl_linux-amd64 /usr/local/bin/cfssl
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo

3.2.2 生成 etcd 证书

(1) 自签证书颁发机构(CA)
创建工作目录

mkdir -p ~/TLS/{etcd,k8s}
cd TLS/etcd

自签 CA:

cat > ca-config.json << EOF
{
	"signing": {
		"default": {
			"expiry": "87600h"
		},
		"profiles": {
			"www": {
		    	"expiry": "87600h",
		     	"usages": [
		       		"signing",
		       		"key encipherment",
		       		"server auth",
		       		"client auth"
		     	]
		    }
		}
	}
}
EOF
cat > ca-csr.json << EOF
{
	"CN": "etcd CA",
	"key": {
		"algo": "rsa",
		"size": 2048
	},
	"names": [
		{
			"C": "CN",
			"L": "Beijing",
			"ST": "Beijing"
		}
	]
}
EOF

生成证书:

cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
ls *pem

ca-key.pem ca.pem

(2) 使用自签 CA 签发 Etcd HTTPS 证书
创建证书申请文件:

cat > server-csr.json << EOF
{
	"CN": "etcd",
	"hosts": [
	    "192.168.0.100",
	    "192.168.0.101",
	    "192.168.0.102"
	],
	"key": {
		"algo": "rsa",
		"size": 2048
	},
	"names": [
		{
			"C": "CN",
			"L": "BeiJing",
			"ST": "BeiJing"
		}
	]
}
EOF

注:上述文件 hosts 字段中 IP 为所有 etcd 节点的集群内部通信 IP,一个都不能少!为了方便后期扩容可以多写几个预留的 IP。

生成证书:

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server
ls server*pem

server-key.pem server.pem

3.2.3 从 Github 下载二进制文件

下载地址 https://github.com/etcd-io/etcd/releases/download/v3.4.9/etcd-v3.4.9-linux-amd64.tar.gz

3.2.4 部署 etcd 集群

以下在 master 节点上操作,为简化操作,待会将 master 节点生成的所有文件拷贝到节点 1 和节点 2

(1) 创建工作目录并解压二进制包

mkdir -p /opt/etcd/{bin,cfg,ssl}
tar zxvf etcd-v3.4.9-linux-amd64.tar.gz
mv etcd-v3.4.9-linux-amd64/{etcd,etcdctl} /opt/etcd/bin

(2) 创建 etcd 配置文件

cat > /opt/etcd/cfg/etcd.conf << EOF
#[Member]
ETCD_NAME="etcd-1"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.0.100:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.0.100:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.0.100:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.0.100:2379"
ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.0.100:2380,etcd-2=https://192.168.0.101:2380,etcd-3=https://192.168.0.102:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
EOF

ETCD_NAME:节点名称,集群中唯一
ETCD_DATA_DIR:数据目录
ETCD_LISTEN_PEER_URLS:集群通信监听地址
ETCD_LISTEN_CLIENT_URLS:客户端访问监听地址
ETCD_INITIAL_ADVERTISE_PEER_URLS:集群通告地址
ETCD_ADVERTISE_CLIENT_URLS:客户端通告地址
ETCD_INITIAL_CLUSTER:集群节点地址
ETCD_INITIAL_CLUSTER_TOKEN:集群 Token
ETCD_INITIAL_CLUSTER_STATE:加入集群的当前状态,new 是新集群,existing 表示加入已有集群

(3) systemctl 管理 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=/opt/etcd/cfg/etcd.conf
ExecStart=/opt/etcd/bin/etcd \
    --name=${ETCD_NAME} \
    --data-dir=${ETCD_DATA_DIR} \
    --listen-peer-urls=${ETCD_LISTEN_PEER_URLS} \
    --listen-client-urls=${ETCD_LISTEN_CLIENT_URLS},http://127.0.0.1:2379 \
    --advertise-client-urls=${ETCD_ADVERTISE_CLIENT_URLS} \
    --initial-advertise-peer-urls=${ETCD_INITIAL_ADVERTISE_PEER_URLS} \
    --initial-cluster=${ETCD_INITIAL_CLUSTER} \
    --initial-cluster-token=${ETCD_INITIAL_CLUSTER_TOKEN} \
    --initial-cluster-state=new \
    --cert-file=/opt/etcd/ssl/server.pem \
    --key-file=/opt/etcd/ssl/server-key.pem \
    --peer-cert-file=/opt/etcd/ssl/server.pem \
    --peer-key-file=/opt/etcd/ssl/server-key.pem \
    --trusted-ca-file=/opt/etcd/ssl/ca.pem \
    --peer-trusted-ca-file=/opt/etcd/ssl/ca.pem \
    --logger=zap
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

(4) 拷贝刚才生成的证书
把刚才生成的证书拷贝到配置文件中的路径:

cp ~/TLS/etcd/ca*pem ~/TLS/etcd/server*pem /opt/etcd/ssl/

(5) 启动并设置开机启动

systemctl daemon-reload
systemctl start etcd
systemctl enable etcd

(6) 将上面 master 节点所有生成的文件拷贝到节点 1 和节点 2

scp -r /opt/etcd/ root@192.168.0.101:/opt/
scp /usr/lib/systemd/system/etcd.service root@192.168.0.101:/usr/lib/systemd/system/
scp -r /opt/etcd/ root@192.168.0.102:/opt/
scp /usr/lib/systemd/system/etcd.service root@192.168.0.102:/usr/lib/systemd/system/

然后在节点 1 和节点 2 分别修改 etcd.conf 配置文件中的节点名称和当前服务器 IP:

vi /opt/etcd/cfg/etcd.conf
#[Member]
ETCD_NAME="etcd-1" # 修改此处,节点 1 改为 etcd-2,节点 2 改为 etcd-3
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.0.100:2380" # 修改此处为当前服务器 IP
ETCD_LISTEN_CLIENT_URLS="https://192.168.0.100:2379" # 修改此处为当前服务器 IP
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.0.100:2380" # 修改此处为当前服务器 IP
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.0.100:2379" # 修改此处为当前服务器 IP
ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.0.100:2380,etcd-2=https://192.168.0.101:2380,etcd-3=https://192.168.0.102:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"

最后启动 etcd 并设置开机启动,同上

(7) 查看集群状态

ETCDCTL_API=3 /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.0.100:2379,https://192.168.0.101:2379,https://192.168.0.102:2379" endpoint health
https://192.168.1.100:2379 is healthy: successfully committed proposal: took = 8.154404ms
https://192.168.1.102:2379 is healthy: successfully committed proposal: took = 9.044117ms
https://192.168.1.101:2379 is healthy: successfully committed proposal: took = 10.000825ms

如果输出上面信息,就说明集群部署成功。如果有问题第一步先看日志:
/var/log/message 或 journalctl -u etcd

3.3 部署 Master Node

3.3.1 生成 kube-apiserver 证书

(1) 自签证书颁发机构 (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",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "Beijing",
            "ST": "Beijing",
            "O": "k8s",
            "OU": "System"
        }
    ]
}
EOF

(2) 生成证书:

cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
ls *pem

ca-key.pem ca.pem

(3) 使用自签 CA 签发 kube-apiserver HTTPS 证书
创建证书申请文件:

cd TLS/k8s
cat > server-csr.json<< EOF
{
    "CN": "kubernetes",
    "hosts": [
        "10.0.0.1",
        "127.0.0.1",
        "192.168.0.100",
        "192.168.0.101",
        "192.168.0.102",
        "192.168.0.103",
        "192.168.0.104",
        "192.168.0.105",
        "192.168.0.106",
        "kubernetes",
        "kubernetes.default",
        "kubernetes.default.svc",
        "kubernetes.default.svc.cluster",
        "kubernetes.default.svc.cluster.local"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "BeiJing",
            "ST": "BeiJing",
            "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
ls server*pem

server-key.pem server.pem

3.3.2 从 Github 下载二进制文件

下载地址:https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.18.md#v1183
注:打开链接你会发现里面有很多包,下载一个 server 包就够了,包含了 Master 和
Worker Node 二进制文件。

3.3.3 解压二进制包

mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}
tar -zxvf kubernetes-server-linux-amd64.tar.gz
cd kubernetes/server/bin
cp kube-apiserver kube-scheduler kube-controller-manager /opt/kubernetes/bin
cp kubectl /usr/bin/

3.3.4 部署 kube-apiserver

(1) 创建配置文件

cat > /opt/kubernetes/cfg/kube-apiserver.conf<< EOF
KUBE_APISERVER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--etcd-servers=https://192.168.0.100:2379,https://192.168.0.101:2379,https://192.168.0.102:2379 \\
--bind-address=192.168.0.100 \\
--secure-port=6443 \\
--advertise-address=192.168.0.100 \\
--allow-privileged=true \\
--service-cluster-ip-range=10.0.0.0/24 \\
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \\
--authorization-mode=RBAC,Node \\
--enable-bootstrap-token-auth=true \\
--token-auth-file=/opt/kubernetes/cfg/token.csv \\
--service-node-port-range=30000-32767 \\
--kubelet-client-certificate=/opt/kubernetes/ssl/server.pem \\
--kubelet-client-key=/opt/kubernetes/ssl/server-key.pem \\
--tls-cert-file=/opt/kubernetes/ssl/server.pem \\
--tls-private-key-file=/opt/kubernetes/ssl/server-key.pem \\
--client-ca-file=/opt/kubernetes/ssl/ca.pem \\
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \\
--etcd-cafile=/opt/etcd/ssl/ca.pem \\
--etcd-certfile=/opt/etcd/ssl/server.pem \\
--etcd-keyfile=/opt/etcd/ssl/server-key.pem \\
--audit-log-maxage=30 \\
--audit-log-maxbackup=3 \\
--audit-log-maxsize=100 \\
--audit-log-path=/opt/kubernetes/logs/k8s-audit.log"
EOF

注:上面两个\ \ 第一个是转义符,第二个是换行符,使用转义符是为了使用 EOF 保留换行符。
-logtostderr:启用日志
--v:日志等级
-log-dir:日志目录
-etcd-servers:etcd 集群地址
-bind-address:监听地址
-secure-port:https 安全端口
-advertise-address:集群通告地址
-allow-privileged:启用授权
-service-cluster-ip-range:Service 虚拟 IP 地址段
-enable-admission-plugins:准入控制模块
-authorization-mode:认证授权,启用 RBAC 授权和节点自管理
-enable-bootstrap-token-auth:启用 TLS bootstrap 机制
-token-auth-file:bootstrap token 文件
-service-node-port-range:Service nodeport 类型默认分配端口范围
-kubelet-client-xxx:apiserver 访问 kubelet 客户端证书
-tls-xxx-file:apiserver https 证书
-etcd-xxxfile:连接 Etcd 集群证书
-audit-log-xxx:审计日志

(2) 拷贝刚才生成的证书
把刚才生成的证书拷贝到配置文件中的路径:

cp ~/TLS/k8s/ca*pem ~/TLS/k8s/server*pem /opt/kubernetes/ssl/

(3) 启用 TLS Bootstrapping 机制
TLS Bootstraping:Master apiserver 启用 TLS 认证后,Node 节点 kubelet 和 kube-
proxy 要与 kube-apiserver 进行通信,必须使用 CA 签发的有效证书才可以,当 Node 节点很多时,这种客户端证书颁发需要大量工作,同样也会增加集群扩展复杂度。为了简化流程,Kubernetes 引入了 TLS bootstraping 机制来自动颁发客户端证书,kubelet 会以一个低权限用户自动向 apiserver 申请证书,kubelet 的证书由 apiserver 动态签署。

TLS bootstraping 工作流程:
在这里插入图片描述创建上述配置文件中 token 文件:

cat > /opt/kubernetes/cfg/token.csv << EOF
5fcb117abee010c9c38895b2d72e5f93,kubelet-bootstrap,10001,"system:node-bootstrapper"
EOF

格式:token,用户名,UID,用户组
token 也可自行生成替换:

head -c 16 /dev/urandom | od -An -t x | tr -d ' '

(4) systemd 管理 apiserver

cat > /usr/lib/systemd/system/kube-apiserver.service << EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-apiserver.conf
ExecStart=/opt/kubernetes/bin/kube-apiserver \$KUBE_APISERVER_OPTS
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF

(5) 启动并设置开机启动

systemctl daemon-reload
systemctl start kube-apiserver
systemctl enable kube-apiserver

(6) 授权 kubelet-bootstrap 用户允许请求证书

kubectl create clusterrolebinding kubelet-bootstrap \
--clusterrole=system:node-bootstrapper \
--user=kubelet-bootstrap

3.3.5 部署 kube-controller-manage

(1) 创建配置文件

cat > /opt/kubernetes/cfg/kube-controller-manager.conf << EOF
KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--leader-elect=true \\
--master=127.0.0.1:8080 \\
--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/24 \\
--cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pem \\
--cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem \\
--root-ca-file=/opt/kubernetes/ssl/ca.pem \\
--service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem \\
--experimental-cluster-signing-duration=87600h0m0s"
EOF

-master:通过本地非安全本地端口 8080 连接 apiserver。
-leader-elect:当该组件启动多个时,自动选举(HA)
-cluster-signing-cert-file/–cluster-signing-key-file:自动为 kubelet 颁发证书的 CA,与 apiserver 保持一致
(2) 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=/opt/kubernetes/cfg/kube-controller-manager.conf
ExecStart=/opt/kubernetes/bin/kube-controller-manager \$KUBE_CONTROLLER_MANAGER_OPTS
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

(3) 启动并设置开机启动

systemctl daemon-reload
systemctl start kube-controller-manager
systemctl enable kube-controller-manager

3.3.6 部署 kube-scheduler

(1) 创建配置文件

cat > /opt/kubernetes/cfg/kube-scheduler.conf << EOF
KUBE_SCHEDULER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--leader-elect \\
--master=127.0.0.1:8080 \\
--bind-address=127.0.0.1"
EOF

-master:通过本地非安全本地端口 8080 连接 apiserver。
-leader-elect:当该组件启动多个时,自动选举(HA)
(2) systemd 管理 scheduler

cat > /usr/lib/systemd/system/kube-scheduler.service << EOF
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes

[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-scheduler.conf
ExecStart=/opt/kubernetes/bin/kube-scheduler \$KUBE_SCHEDULER_OPTS
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

(3) 启动并设置开机启动

systemctl daemon-reload
systemctl start kube-scheduler
systemctl enable kube-scheduler

(4) 查看集群状态
所有组件都已经启动成功,通过 kubectl 工具查看当前集群组件状态:

kubectl get cs

在这里插入图片描述如上输出说明 Master 节点组件运行正常。

3.4 安装 Docker

以下在所有 Work Node 节点操作。这里采用二进制安装,用 yum 安装也一样。
(1) 下载安装包
地址:https://download.docker.com/linux/static/stable/x86_64/docker-19.03.9.tgz

tar -zxvf docker-19.03.9.tgz
mv docker/* /usr/bin

(2) systemd 管理 docker

cat > /usr/lib/systemd/system/docker.service << EOF
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target

[Service]
Type=notify
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s

[Install]
WantedBy=multi-user.target
EOF

(3) 创建配置文件

mkdir -p /etc/docker
cat > /etc/docker/daemon.json << EOF
{
  "registry-mirrors": ["https://m5fsbji5.mirror.aliyuncs.com"]
}
EOF

(4) 启动并设置开机启动

systemctl daemon-reload
systemctl start docker
systemctl enable docker

3.5 部署 Worker Node

下面还是在 Master Node 上操作,即同时作为 Worker Node

3.5.1 创建工作目录并拷贝二进制文件

在所有 worker node 创建工作目录:

mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}

从 master 节点拷贝:

cd kubernetes/server/bin
scp kubelet kube-proxy root@192.168.0.101:/opt/kubernetes/bin
cd ~/TLS/k8s/
scp ca.pem root@192.168.0.101:/opt/kubernetes/ssl

3.5.2 部署 kubelet

(1) 创建配置文件

cat > /opt/kubernetes/cfg/kubelet.conf << EOF
KUBELET_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--hostname-override=node1 \\
--network-plugin=cni \\
--kubeconfig=/opt/kubernetes/cfg/kubelet.kubeconfig \\
--bootstrap-kubeconfig=/opt/kubernetes/cfg/bootstrap.kubeconfig \\
--config=/opt/kubernetes/cfg/kubelet-config.yml \\
--cert-dir=/opt/kubernetes/ssl \\
--pod-infra-container-image=lizhenliang/pause-amd64:3.0"
EOF

-hostname-override:显示名称,集群中唯一
-network-plugin:启用 CNI
-kubeconfig:空路径,会自动生成,后面用于连接 apiserver
-bootstrap-kubeconfig:首次启动向 apiserver 申请证书
-config:配置参数文件
-cert-dir:kubelet 证书生成目录
-pod-infra-container-image:管理 Pod 网络容器的镜像

(2) 配置参数文件

cat > /opt/kubernetes/cfg/kubelet-config.yml << EOF
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
address: 0.0.0.0
port: 10250
readOnlyPort: 10255
cgroupDriver: cgroupfs
clusterDNS:
- 10.0.0.2
clusterDomain: cluster.local
failSwapOn: false
authentication:
    anonymous:
        enabled: false
    webhook:
        cacheTTL: 2m0s
        enabled: true
    x509:
        clientCAFile: /opt/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

(3) 生成 bootstrap.kubeconfig 文件

KUBE_APISERVER="https://192.168.0.100:6443" # apiserver IP:PORT
TOKEN="5fcb117abee010c9c38895b2d72e5f93" # 与 token.csv 里保持一致
# 生成 kubelet bootstrap kubeconfig 配置文件
kubectl config set-cluster kubernetes \
    --certificate-authority=/opt/kubernetes/ssl/ca.pem \
    --embed-certs=true \
    --server=${KUBE_APISERVER} \
    --kubeconfig=bootstrap.kubeconfig
kubectl config set-credentials "kubelet-bootstrap" \
    --token=${TOKEN} \
    --kubeconfig=bootstrap.kubeconfig
kubectl config set-context default \
    --cluster=kubernetes \
    --user="kubelet-bootstrap" \
    --kubeconfig=bootstrap.kubeconfig
kubectl config use-context default --kubeconfig=bootstrap.kubeconfig

拷贝到配置文件路径:

scp bootstrap.kubeconfig root@192.168.0.101:/opt/kubernetes/cfg
scp bootstrap.kubeconfig root@192.168.0.102:/opt/kubernetes/cfg

(4) systemd 管理 kubelet

cat > /usr/lib/systemd/system/kubelet.service << EOF
[Unit]
Description=Kubernetes Kubelet
After=docker.service

[Service]
EnvironmentFile=/opt/kubernetes/cfg/kubelet.conf
ExecStart=/opt/kubernetes/bin/kubelet \$KUBELET_OPTS
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

(5) 启动并设置开机启动

systemctl daemon-reload
systemctl start kubelet
systemctl enable kubelet

3.5.3 批准 kubelet 证书申请并加入集群

查看 kubelet 证书请求

kubectl get csr

批准申请

kubectl certificate approve node-csr-qBnlB-UGCHYDwT2RBbSbyff30BxVeEYeIasYMoKp0sY

查看节点

kubectl get node

在这里插入图片描述

注:由于网络插件还没有部署,节点会没有准备就绪 NotReady

3.5.4 部署 kube-proxy

(1) 创建配置文件

cat > /opt/kubernetes/cfg/kube-proxy.conf << EOF
KUBE_PROXY_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--config=/opt/kubernetes/cfg/kube-proxy-config.yml"
EOF

(2) 配置参数文件

cat > /opt/kubernetes/cfg/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: /opt/kubernetes/cfg/kube-proxy.kubeconfig
hostnameOverride: node1
clusterCIDR: 10.0.0.0/24
EOF

hostnameOverride 需要修改
(3) 生成 kube-proxy.kubeconfig 文件
生成 kube-proxy 证书:
切换目录

cd TLS/k8s

创建证书请求文件

cat > kube-proxy-csr.json<< EOF
{
    "CN": "system:kube-proxy",
    "hosts": [],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "BeiJing",
            "ST": "BeiJing",
            "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
ls kube-proxy*pem

kube-proxy-key.pem kube-proxy.pem

生成 kubeconfig 文件:

KUBE_APISERVER="https://192.168.0.100:6443"
kubectl config set-cluster kubernetes \
    --certificate-authority=/opt/kubernetes/ssl/ca.pem \
	  --embed-certs=true \
    --server=${KUBE_APISERVER} \
    --kubeconfig=kube-proxy.kubeconfig
kubectl config set-credentials kube-proxy \
    --client-certificate=./kube-proxy.pem \
    --client-key=./kube-proxy-key.pem \
    --embed-certs=true \
    --kubeconfig=kube-proxy.kubeconfig
kubectl config set-context default \
    --cluster=kubernetes \
    --user=kube-proxy \
    --kubeconfig=kube-proxy.kubeconfig
kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig  

拷贝到配置文件指定路径:

scp kube-proxy.kubeconfig root@192.168.0.101:/opt/kubernetes/cfg/

(4) systemd 管理 kube-proxy

cat > /usr/lib/systemd/system/kube-proxy.service << EOF
[Unit]
Description=Kubernetes Proxy
After=network.target

[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-proxy.conf
ExecStart=/opt/kubernetes/bin/kube-proxy \$KUBE_PROXY_OPTS
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

(5) 启动并设置开机启动

systemctl daemon-reload
systemctl start kube-proxy
systemctl enable kube-proxy

3.6 部署 CNI 网络

下载地址:https://github.com/containernetworking/plugins/releases/download/v0.8.6/cni-plugins-linux-amd64-v0.8.6.tgz

mkdir -p /opt/cni/bin
tar -zxvf cni-plugins-linux-amd64-v0.8.6.tgz -C /opt/cni/bin

部署 CNI 网络:

wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
sed -i -r "s#quay.io/coreos/flannel:.*-amd64#lizhenliang/flannel:v0.12.0-amd64#g" kube-flannel.yml

默认镜像地址无法访问,修改为 docker hub 镜像仓库。

应用网络

kube-flannel.yaml

kubectl apply -f kube-flannel.yaml

查看网络

kubectl get pods -n kube-flannel

查看节点

kubectl get nodes

测试 kubernetes 集群
在 kubernetes 集群中创建一个 pods,验证是否正常运行

kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePort
kubectl get pod,svc

在这里插入图片描述在这里插入图片描述

3.7 授权 apiserver 访问 kubelet

apiserver-to-kubelet-rbac.yaml

kubectl apply -f apiserver-to-kubelet-rbac.yaml

查看

kubectl get ClusterRole

image-20221110122528171

第四部分 kubernetes 集群 YAML 文件详解

4.1 YAML 文件概述

k8s 集群中对资源管理和资源对象编排部署都可以通过声明样式(YAML)文件来解决,也就是可以把需要对资源对象操作编辑到 YAML 格式文件中,我们把这种文件叫做资源清单文件,通过 kubectl 命令直接使用资源清单文件就可以实现对大量的资源对象进行编排部署了。

4.2 YAML 文件书写形式

4.2.1 YAML 介绍

YAML:仍是一种标记语言。为了强调这种语言以数据做为中心,而不是以标记语言为重点。

YAML 是一个可读性高,用来表达数据序列的格式。

4.2.2 YAML 基本语法

  • 使用空格做为缩进
  • 通过缩进表示层级关系,缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
  • 低版本缩进时不允许使用 Tab 键,只允许使用空格
  • 一般开头缩进两个空格
  • 字符后缩进一个空格,比如 冒号、逗号后面
  • 使用 "---" 表示新的文件
  • 使用 "#" 标识注释,从这个字符一直到行尾,都会被解释器忽略

4.3 资源清单描述方法

4.3.1 YAML 文件组成部分

  • 控制器定义
  • 被控制对象
  • 在这里插入图片描述

在这里插入图片描述

4.3.2 如何快速编写 yaml 文件

  • 使用 kubectl create 命令生成 yaml 文件
kubectl create deployment web --image=nginx -o yaml --dry-run > my1.yaml

"-o" 输出成 yaml 格式
"--dry-run" 不实际执行
"> my1.yaml" 输出到 my1.yaml 文件

  • 使用 kubectl get 命令导出 yaml 文件
kubectl get deploy nginx -o yaml > my2.yaml

4.3.3 常用字段

在这里插入图片描述

第五部分 kubernetes 集群命令行工具 kubectl

5.1 kubectl 概述

kubectl 是 Kubernetes 集群的命令行工具,通过 kubectl 能够对集群本身进行管理,并能够在集群上进行容器化应用的安装部署。

5.2 kubectl 命令的语法

kubectl [command] [TYPE] [NAME] [flags]

(1) comand:指定要对资源执行的操作,例如 create、get、describe 和 delete
(2) TYPE:指定资源类型,资源类型是大小写敏感的,开发者能够以单数、复数和缩略的形式。例如:

kubectl get pod pod1
kubectl get pods pod1
kubectl get po pod1

(3) NAME:指定资源的名称,名称也大小写敏感的。如果省略名称,则会显示所有的资源,例如:

kubectl get pods

(4) flags:指定可选的参数。例如,可用 -s 或者–server 参数指定 Kubernetes API server 的地址和端口。

5.3 kubectl help 获取更多信息

kubectl get --help

5.4 kubectl 子命令使用分类

(1) 基础命令
在这里插入图片描述
(2) 部署和集群管理命令
在这里插入图片描述
(3) 故障和调试命令
在这里插入图片描述
(4) 其他命令
在这里插入图片描述

第六部分 kubernetes 核心技术 Pod

6.1 Pod 概述

Pod 是 k8s 系统中可以创建和管理的最小单元,是资源对象模型中由用户创建或部署的最小资源对象模型,也是在 k8s 上运行容器化应用的资源对象,其他的资源对象都是用来支撑或者扩展 Pod 对象功能的,比如控制器对象是用来管控 Pod 对象的,Service 或者 Ingress 资源对象是用来暴露 Pod 引用对象的,PersistentVolume 资源对象是用来为 Pod 提供存储等等,k8s 不会直接处理容器,而是 Pod,Pod 是由一个或多个 container 组成

Pod 是 Kubernetes 的最重要概念,每一个 Pod 都有一个特殊的被称为”根容器“的 Pause 容器。Pause 容器对应的镜像属于 Kubernetes 平台的一部分,除了 Pause 容器,每个 Pod 还包含一个或多个紧密相关的用户业务容器
在这里插入图片描述(1) Pod vs 应用
每个 Pod 都是应用的一个实例,有专用的 IP
(2) Pod vs 容器
一个 Pod 可以有多个容器,彼此间共享网络和存储资源,每个 Pod 中有一个 Pause 容器保存所有的容器状态, 通过管理 pause 容器,达到管理 pod 中所有容器的效果
(3) Pod vs 节点
同一个 Pod 中的容器总会被调度到相同 Node 节点,不同节点间 Pod 的通信基于虚拟二层网络技术实现
(4) Pod vs Pod
普通的 Pod 和静态 Pod
请添加图片描述

6.2 Pod 实现机制

  • 共享网络
    请添加图片描述
  • 共享存储
    请添加图片描述
    请添加图片描述

6.3 Pod 镜像拉取策略

请添加图片描述

  • IfNotPresent:默认值,镜像在宿主机上不存在时才拉取
  • Always:每次创建Pod都会重新拉取一次镜像
  • Never:Pod永远不会主动拉取这个镜像

6.4 Pod 资源限制

请添加图片描述

6.5 Pod 重启机制

请添加图片描述

6.6 Pod 健康检查

请添加图片描述

6.7 创建 Pod 流程

请添加图片描述

6.8 Pod 调度

影响调度的属性:

  • Pod 资源限制:根据 request 找到足够 node 节点进行调度
    在这里插入图片描述
  • 节点选择器标签
    请添加图片描述
kubectl label node node1 env_role=dev
kubectl get nodes --show-labels
kubectl describe node node1 | grep env_role

在这里插入图片描述

  • 节点亲和性
    请添加图片描述
  • 污点和污点容忍
    请添加图片描述
    污点查看
kubectl describe nodes | grep Taint

在这里插入图片描述
添加污点

kubectl taint node node1 env_roles=yes:NoSchedule
kubectl describe node node1 | grep Taint

在这里插入图片描述
删除污点

kubectl taint node node1 env_roles:NoSchedule-

污点容忍:
请添加图片描述

第七部分 kubernetes 核心技术 Controller(Deployment)

请添加图片描述

7.1 Pod 和 Controller 的关系

在这里插入图片描述

7.2 使用 deployment 部署应用 (yaml)

  1. 导出 YAML 文件
kubectl create deployment web --image=nginx -o yaml --dry-run > web.yaml

web.yaml

  1. 使用 YAML 部署应用
kubectl apply -f web.yaml
  1. 对外发布(暴露对外端口号)
kubectl expose deployment web --port=80 --type=NodePort --target-port=80 --name=web1 -o yaml > web1.yaml
kubectl apply -f web1.yaml

web1.yaml

  1. 查看
kubectl get pods,svc

在这里插入图片描述

7.3 应用升级回滚和弹性伸缩

image-20221109153744750

  1. 应用升级
kubectl set image deployment web nginx=nginx:1.15

image-20221109154058436

image-20221109154321744

  1. 查看升级状态
kubectl rollout status deployment web

image-20221109155757838

  1. 查看升级历史
kubectl rollout history deployment web

image-20221109155932533

  1. 回滚到上一个版本
kubectl rollout undo deployment web

image-20221109160320731

  1. 回滚到指定版本
kubectl rollout undo deployment web --to-revision=2
  1. 弹性伸缩
kubectl scale deployment web --replicas=10

第八部分 kubernetes 核心技术-Service

Service 是 Kubernetes 最核心概念,通过创建 Service,可以为一组具有相同功能的容器应用提供一个统一的入口地址,并且将请求负载分发到后端的各个容器应用上。

20-Service

第九部分 kubernetes 核心技术 Controller(StatefulSet)

21-controller

9.1 部署有状态应用

sts.yaml

image-20221110091506687

kubectl apply -f sts.yaml

image-20221110091955377

kubectl get pods,svc

image-20221110092357892

9.2 部署守护进程 DaemonSet

ds.yaml

kubectl apply -f ds.yaml
kubectl get pods

image-20221110120602463

kubectl exec -it ds-test-c747v -- bash

image-20221110120714671

9.3 Job 一次性任务

job.yaml

部署

kubectl apply -f job.yaml

image-20221110140148235

查看

kubectl get jobs

image-20221110140229445

kubectl logs pi-llnz7

image-20221110140425739

删除

kubectl delete -f job.yaml

9.4 cronjob 定时任务

cronjob.yaml

image-20221110143244219

部署

kubectl apply -f cronjob.yaml

image-20221110143341738

查看

kubectl get cronjobs

image-20221110143504568

查看日志

image-20221110144142044

第十部分 kubernetes 核心技术 Secret

22-配置管理-secret

Secret 解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者 Pod Spec 中。Secret 可以以 Volume 或者环境变量的方式使用

# base64编码
echo -n 'admin' | base64

image-20221110144630052

10.1 创建 secret 加密数据

secret.yaml

部署并查看

kubectl apply -f secret.yaml
kubectl get secret

image-20221110145326286

10.2 以变量形式挂载到pod容器中

secret-var.yaml

image-20221110145949490image-20221110150128300

部署

kubectl apply -f secret-var.yaml

image-20221110150534473

进入查看

kubectl exec -it mypod -- bash
echo $SECRET_USERNAME
echo $SECRET_PASSWORD

image-20221110151401281

10.3 以 Volume 形式挂载 pod 容器中

secret-vol.yaml

image-20221110151622280

部署

kubectl apply -f secret-vol.yaml

image-20221110151815238

进入查看

kubectl exec -it mypod -- bash
cat /etc/foo/password
cat /etc/foo/username

image-20221110152040222

第十一部分 kubernetes 核心技术 configmap

23-配置管理-configMap

11.1 创建配置文件

redis.properties

11.2 创建 configmap 并查看

kubectl create configmap redis-config --from-file=redis.properties
kubectl get cm
kubectl describe cm redis-config

image-20221110153640481

11.3 以 Volume 形式挂载 pod 容器中

cm.yaml

image-20221110153944153

部署

kubectl apply -f cm.yaml

image-20221110154154245

查看

kubectl get pods
kubectl logs mypod

image-20221110154343755

11.4 以变量形式挂载到pod容器中

创建 yaml,声明变量信息

myconfig.yaml

创建 configmap 并查看

image-20221110155252618

以变量形式挂载

config-var.yaml

image-20221110155551964

部署

kubectl apply -f config-var.yaml
kubectl get pods

image-20221110155721695

查看

kubectl logs mypod

image-20221110155850375

第十二部分 kubernetes 核心技术集群安全机制 RBAC

12.1 RBAC 介绍

24-k8s集群安全机制

12.2 RBAC 实现鉴权

创建命名空间

kubectl create ns roledemo
kubectl get ns

image-20221110162429332

在创建的命名空间中创建 pod

kubectl run nginx --image=nginx -n roledemo
kubectl get pods -n roledemo

image-20221110163106623

创建角色

rbac-role.yaml

kubectl apply -f rbac-role.yaml
kubectl get role -n roledemo

image-20221110164118439

创建角色绑定

rbac-rolebinding.yaml

image-20221110164655089

kubectl apply -f rbac-rolebinding.yaml
kubectl get role,rolebinding -n roledemo

image-20221110164500786

使用证书识别身份

rabc-user.sh

mkdir mary && cd mary
cp ../rabc-user.sh .
ls

image-20221110165750747

vi rabc-user.sh

修改 ip 地址

image-20221110165944778

cp /root/TLS/k8s/{ca.pem,ca-key.pem,ca-config.json} ./
ls

image-20221110170748459

bash rabc-user.sh
ls

image-20221110171225687

kubectl get pods -n roledemo --kubeconfig=./mary-kubeconfig
kubectl get ns -n roledemo --kubeconfig=./mary-kubeconfig
kubectl get svc -n roledemo --kubeconfig=./mary-kubeconfig

image-20221110171554178

第十三部分 kubernetes 核心技术 Ingress

26-ingress

使用 Ingress 对外暴露应用

创建 nginx 应用,对外暴露端口使用 NodePort

创建 deployment \(\to\) nginx

kubectl create deployment web --image=nginx
kubectl get pods,deploy

image-20221111105832596

暴露端口

kubectl expose deployment web --port=80 --target-port=80 --type=NodePort
kubectl get svc

image-20221111110007786

部署 Ingress Controller

ingress-controller.yaml

image-20221111100921758

kubectl apply -f ingress-controller.yaml
kubectl get pods -n ingress-nginx

创建 Ingress 规则

ingress01.yaml

image-20221111101731308

kubectl apply -f ingress01.yaml

image-20221111101839096

kubectl get pods -n ingress-nginx -o wide
kubectl get svc,ingress

image-20221111110147310

在 windows 系统 hosts 文件中添加域名访问规则

hosts

image-20221111130716635

第十四部分 kubernetes 核心技术 Helm

14.1 Helm 概述

28-helm(概述)

14.2 Helm 安装和配置仓库

29-helm(快速部署应用)

14.3 helm 安装

下载

链接:https://get.helm.sh/helm-v3.0.0-linux-amd64.tar.gz

解压安装

tar -zxvf helm-v3.0.0-linux-amd64.tar.gz
cd linux-amd64
mv helm /usr/bin/ && cd ~ && rm -rf linux-amd64/
helm version

image-20221111150309143

14.4 配置 helm 仓库

添加并更新仓库

helm repo add stable http://mirror.azure.cn/kubernetes/charts
helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
helm repo list
helm repo update

image-20221111151057546

删除仓库

helm repo remove aliyun
helm repo list
helm repo update

image-20221111151317463

14.5 使用 helm 快速部署应用

搜索应用

# helm search repo [name]
helm search repo weave

image-20221111152014378

根据搜索内容选择安装

安装应用

# helm install [name] [chart]
helm install ui stable/weave-scope

image-20221111152234457

查看应用

helm list
helm status [name]

image-20221111152437395

查看 pod 和 service

kubectl get pods,svc

image-20221111152628638

修改 service 的 yaml 文件,type 改为 NodePort

kubectl edit svc ui-weave-scope
kubectl get svc

image-20221111153246757

14.6 自定义 Chart 部署

30-helm(自己创建chart)

创建 chart 模板

helm create mychart

image-20221111164252893

  • Chart.yaml: chart 基本信息
  • templates: 模板,放自己编写的 yaml 文件
  • values.yaml: yaml 文件可以使用的全局变量

创建 yaml 文件

cd templates
kubectl create deployment web1 --image=nginx --dry-run -o yaml > deployment.yaml

image-20221111165129125

kubectl expose deployment web1 --port=80 --target-port=80 --type=NodePort --dry-run -o yaml > service.yaml
ls

image-20221111165758104

安装 mychart

helm install web1 mychart
kubectl get pods,svc

image-20221111165957773

应用升级

# helm upgrade [name] [chart]
helm upgrade web1 mychart

image-20221111170229745

14.7 yaml 高效复用

31-helm(chart模板)

在 valuse.yaml 文件中定义变量和值

image-20221111171544614

在 templates 的 yaml 文件中使用 values.yaml 定义的变量

# {{ .Values.变量名称}}
# 比如 {{ .Release.Name}}

image-20221111172904338

image-20221111172939539

helm install web2 mychart/
kubectl get pods,svc

image-20221111172656147

第十五部分 kubernetes 核心技术 持久化存储

36-持久存储-nfs

15.1 找一台机器当作 nfs 服务端

安装 nfs

yum install -y nfs-utils

设置挂载路径

cat > /etc/exports << EOF
/data/nfs *(rw,no_root_squash)
EOF

image-20221114095615033

mkdir -p /data/nfs
ls /data/

image-20221114095717492

15.2 在 k8s 集群 node 节点上安装 nfs

yum install -y nfs-utils

image-20221114100438618image-20221114100457712

15.3 在 nfs 服务端启动 nfs 服务

systemctl start nfs
ps -ef | grep nfs

image-20221114100841200

systemctl stop firewalld && systemctl disable firewalld

15.4 在 k8s 集群部署应用—使用 nfs 持久网络存储

创建 pod 挂载 nfs

nfs-nginx.yaml

kubectl apply -f nfs-nginx.yaml
kubectl get pods

image-20221114105429005

查看 nfs 效果

进入容器

kubectl exec -it nginx-dep1-75cb9bfbcb-fflg9 -- bash
ls /usr/share/nginx/html

image-20221114105840103

在容器中创建一个 index01.html 文件

echo "hello nfs01" >> /usr/share/nginx/html/index01.html
cat /usr/share/nginx/html/index01.html

image-20221114110102874

进入 nfs 服务端

ls /data/nfs/
cat /data/nfs/index01.html

image-20221114110315847

在服务端创建一个 index.html 文件

echo "Hello dfuttu" >> /data/nfs/index.html
cat /data/nfs/index.html

image-20221114110600864

容器中查看并退出容器

cat /usr/share/nginx/html/index.html
exit

image-20221114110808056

创建 service 对外暴露端口

kubectl expose deployment nginx-dep1 --port=80 --target-port=80 --type=NodePort
kubectl get svc

image-20221114111153720

image-20221114111254740

15.5 pv 和 pvc

37-持久存储-pv和pvc

创建 pv, pvc

pv.yaml

pvc.yaml

kubectl apply -f pvc.yaml
kubectl apply -f pv.yaml
kubectl get pods
kubectl get pv,pvc

image-20221114112423912

查看 pv, pvc 效果

kubectl exec -it nginx-dep1-58b7bf955f-t6rsc -- bash
ls /usr/share/nginx/html/

image-20221114112708482

第十六部分 kubernetes 核心技术 集群资源监控

27-集群监控平台

16.1 部署 prometheus

部署守护进程

node-exporter.yaml

image-20221114121422147

kubectl create -f node-exporter.yaml
kubectl get daemonset,svc -n kube-system

image-20221114122628647

访问权限

rbac-setup.yaml

kubectl create -f ./prometheus/rbac-setup.yaml

image-20221114122850278

配置文件

configmap.yaml

kubectl create -f ./prometheus/configmap.yaml

image-20221114123016374

部署 Depolyment

prometheus.deploy.yml

kubectl create -f ./prometheus/prometheus.deploy.yml
kubectl get deploy -n kube-system

image-20221114123322141

部署 Service

prometheus.svc.yml

kubectl create -f ./prometheus/prometheus.svc.yml
kubectl get deploy,svc -n kube-system

image-20221114123540801

查看

kubectl get pods,deploy,svc -n kube-system

image-20221114123715922

16.2 部署 Grafnan

Deployment

grafana-deploy.yaml

kubectl create -f ./grafana/grafana-deploy.yaml

Service

grafana-svc.yaml

kubectl create -f ./grafana/grafana-svc.yaml

Ingress

grafana-ing.yaml

kubectl create -f ./grafana/grafana-ing.yaml

image-20221114124431628

查看

kubectl get all -n kube-system

image-20221114125123344

16.3 打开 Grafana,配置数据源,导入显示模板

第十七部分 kubernetes 集群搭建-搭建高可用集群

34-搭建高可用的集群

35-搭建高可用的集群

节点 IP
master1 192.168.0.101
master1 192.168.0.102
node1 192.168.0.103
node2 192.168.0.104
node3 192.168.0.105
VIP 192.168.0.106

17.1 系统初始化

关闭防火墙

# 临时关闭
systemctl stop firewalld
# 永久关闭
systemctl disable firewalld

关闭 selinux

# 永久
sed -i 's/enforcing/disabled/' /etc/selinux/config
# 临时
setenforce 0

关闭 swap

# 临时
swapoff -a
# 永久
sed -ri 's/.*swap.*/#&/' /etc/fstab

更改主机名

hostnamectl set-hostname <hostname>

在 master 添加 hosts

cat >> /etc/hosts << EOF
192.168.0.106   master.k8s.io   k8s-vip
192.168.0.101   master01.k8s.io master1
192.168.0.102   master02.k8s.io master2
192.168.0.103   node01.k8s.io   node1
192.168.0.104   node02.k8s.io   node2
192.168.0.105   node03.k8s.io   node3
EOF

将桥接的 IPv4 流量传递到 iptables 的链

cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
# 生效
sysctl --system

时间同步

yum install ntpdate -y
ntpdate time.windows.com

17.2 所有 master 节点部署 keepalived

安装相关包和 keepalived

yum install -y conntrack-tools libseccomp libtool-ltdl keepalived

配置 master 节点

master1 节点配置

cat > /etc/keepalived/keepalived.conf << EOF
! Configuration File for keeplived

global_defs {
    router_id k8s
}

vrrp_script check_haproxy {
    script "killall -0 haproxy"
    interval 3
    weight -2
    fall 10
    rise 2
}

vrrp_instance VI_1 {
    state MASTER
    interface ens32
    virtual_router_id 51
    priority 250
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass ceb1b3ec013d66163d6ab
    }
    virtual_ipaddress {
        192.168.0.106
    }
    track_script {
        check_haproxy
    }

}
EOF

vrrp_script: 指定检查 nginx 工作状态脚本(根据 nginx 状态判断是否故障转移)
virtual_ipaddress: 虚拟 IP(VIP)

master2 节点配置

cat > /etc/keepalived/keepalived.conf <<EOF 
! Configuration File for keepalived

global_defs {
   router_id k8s
}

vrrp_script check_haproxy {
    script "killall -0 haproxy"
    interval 3
    weight -2
    fall 10
    rise 2
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens32
    virtual_router_id 51
    priority 200
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass ceb1b3ec013d66163d6ab
    }
    virtual_ipaddress {
        192.168.0.106
    }
    track_script {
        check_haproxy
    }

}
EOF

启动和检查

在两台master节点都执行

# 启动keepalived
systemctl start keepalived.service
# 设置开机启动
systemctl enable keepalived.service
# 查看启动状态
systemctl status keepalived.service

启动后查看master的网卡信息

ip a s ens32

image-20221114161735405

17.3 所有 master 节点部署 haproxy

haproxy 主要做负载,将请求分担到不同的 node 节点上

安装

yum install -y haproxy

配置

两台 master 节点的配置均相同,配置中声明了后端代理的两个 master 节点服务器,指定了 haproxy 运行的端口为 16443 等,因此 16443 端口为集群的入口

cat > /etc/haproxy/haproxy.cfg << EOF
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    # to have these messages end up in /var/log/haproxy.log you will
    # need to:
    # 1) configure syslog to accept network log events.  This is done
    #    by adding the '-r' option to the SYSLOGD_OPTIONS in
    #    /etc/sysconfig/syslog
    # 2) configure local2 events to go to the /var/log/haproxy.log
    #   file. A line like the following can be added to
    #   /etc/sysconfig/syslog
    #
    #    local2.*                       /var/log/haproxy.log
    #
    log         127.0.0.1 local2
    
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon 
       
    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------  
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000
#---------------------------------------------------------------------
# kubernetes apiserver frontend which proxys to the backends
#--------------------------------------------------------------------- 
frontend kubernetes-apiserver
    mode                 tcp
    bind                 *:16443
    option               tcplog
    default_backend      kubernetes-apiserver    
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend kubernetes-apiserver
    mode        tcp
    balance     roundrobin
    server      master01.k8s.io   192.168.0.101:6443 check
    server      master02.k8s.io   192.168.0.102:6443 check
#---------------------------------------------------------------------
# collection haproxy statistics message
#---------------------------------------------------------------------
listen stats
    bind                 *:1080
    stats auth           admin:awesomePassword
    stats refresh        5s
    stats realm          HAProxy\ Statistics
    stats uri            /admin?stats
EOF

启动和检查

systemctl start haproxy
systemctl enable haproxy
systemctl status haproxy

查看对应的端口是否包含 16443

netstat -tunlp | grep haproxy

17.4 所有节点安装 Docker、Kubeadm、kubectl

Kubernetes 默认 CRI(容器运行时)为 Docker,因此先安装 Docker

安装 docker

(1) 下载安装包
地址:https://download.docker.com/linux/static/stable/x86_64/docker-19.03.9.tgz

tar -zxvf docker-18.06.1.tgz
mv docker/* /usr/bin

(2) systemd 管理 docker

cat > /usr/lib/systemd/system/docker.service << EOF
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target

[Service]
Type=notify
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s

[Install]
WantedBy=multi-user.target
EOF

(3) 创建配置文件

mkdir -p /etc/docker
cat > /etc/docker/daemon.json << EOF
{
  "registry-mirrors": ["https://m5fsbji5.mirror.aliyuncs.com"]
}
EOF

(4) 启动并设置开机启动

systemctl daemon-reload
systemctl start docker
systemctl enable docker

docker version

添加 kubernetes 阿里云 yum 源

cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
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

安装 kubeadm,kubelet 和 kubectl

yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0
systemctl enable kubelet

17.5 部署 Kubernetes Master

创建 kubeadm 配置文件

在具有 vip 的 master 上进行初始化操作,这里为 master1

image-20221115095537723

# 创建文件夹
mkdir /usr/local/kubernetes/manifests -p
# 到 manifests 目录
cd /usr/local/kubernetes/manifests/
# 新建yaml文件
vi kubeadm-config.yaml

yaml 文件内容如下:

apiServer:
  certSANs:
    - master1
    - master2
    - master.k8s.io
    - 192.168.0.106
    - 192.168.0.101
    - 192.168.0.102
    - 127.0.0.1
  extraArgs: 
    authorization-mode: Node,RBAC
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta1
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controlPlaneEndpoint: "master.k8s.io:16443"
controllerManager: {}
dns:
  type: CoreDNS
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.18.0
networking:
  dnsDomain: cluster.local
  podSubnet: 10.244.0.0/16
  serviceSubnet: 10.1.0.0/16
scheduler: {}

在 master1 节点执行

kubeadm init --config kubeadm-config.yaml

image-20221115102608986

docker images

image-20221115101248904

按照提示配置环境变量,使用kubectl工具

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 nodes
# 查看pod
kubectl get pods -n kube-system

image-20221115103047667

按照提示保存以下内容,一会要使用:

kubeadm join master.k8s.io:16443 --token 2g9r17.027egoffetrqtdda \
    --discovery-token-ca-cert-hash sha256:936b1db1ab0ab1240719d414be2843b2e499c57d5241f450fbf7daff1e71dc1a \
    --control-plane

查看集群状态

# 查看集群状态
kubectl get cs
# 查看pod
kubectl get pods -n kube-system

image-20221115103255611

17.6 安装集群网络

从官方地址获取到 flannel 的 yaml,在 master1 上执行

kube-flannel.yml

# 创建文件夹
mkdir flannel && cd flannel
# 下载yaml文件
wget -c https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

安装 flannel 网络

kubectl apply -f kube-flannel.yml

image-20221115104524951

检查

kubectl get pods -n kube-flannel
kubectl get nodes
kubectl get pods -n kube-system

image-20221115104841932

17.7 master2 节点加入集群

复制密钥和相关文件

从 master1 复制密钥及相关文件到 master2

ssh root@192.168.0.102 mkdir -p /etc/kubernetes/pki/etcd

scp /etc/kubernetes/admin.conf root@192.168.0.102:/etc/kubernetes
   
scp /etc/kubernetes/pki/{ca.*,sa.*,front-proxy-ca.*} root@192.168.0.102:/etc/kubernetes/pki
   
scp /etc/kubernetes/pki/etcd/ca.* root@192.168.0.102:/etc/kubernetes/pki/etcd

image-20221115105558746

image-20221115105447496

master2 节点加入集群

执行在 master1 上 init 后保存的命令,参数 --control-plane 表示把 master 控制节点加入集群

kubeadm join master.k8s.io:16443 --token 2g9r17.027egoffetrqtdda \
    --discovery-token-ca-cert-hash sha256:936b1db1ab0ab1240719d414be2843b2e499c57d5241f450fbf7daff1e71dc1a \
    --control-plane

按照提示配置环境变量,使用kubectl工具

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

kubectl get pods --all-namespaces

image-20221115110223724

17.8 加入 Kubernetes Node

在 node 上执行

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

kubeadm join master.k8s.io:16443 --token 2g9r17.027egoffetrqtdda \
    --discovery-token-ca-cert-hash sha256:936b1db1ab0ab1240719d414be2843b2e499c57d5241f450fbf7daff1e71dc1a

image-20221115111652729

重新安装网络

kubectl delete -f kube-flannel.yml
kubectl apply -f kube-flannel.yml

image-20221115112206205

17.9 测试 kubernetes 集群

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

# 创建nginx deployment
kubectl create deployment nginx --image=nginx
# 暴露端口
kubectl expose deployment nginx --port=80 --type=NodePort
# 查看状态
kubectl get pod,svc

image-20221115113317547

image-20221115113404593

第十八部分 k8s 集群部署项目

18.1 部署流程

32-部署项目流程介绍

18.2 部署

33-部署java项目

制作镜像

docker build -t java-demo-01 .

image-20221115154532807

测试镜像

docker run -td -p 8111:8111 java-demo-01

浏览器访问 http:192.168.0.102:8111/user

image-20221115155207741

上传镜像

登录

docker login --username=dfuttu registry.cn-hangzhou.aliyuncs.com

image-20221115155857399

改名

docker tag java-demo-01:latest registry.cn-hangzhou.aliyuncs.com/dfuttu/java-demo-01:1.0.0

image-20221115160050687

推送

docker push registry.cn-hangzhou.aliyuncs.com/dfuttu/java-demo-01:1.0.0

image-20221115160221180

拉取

docker login --username=dfuttu registry.cn-hangzhou.aliyuncs.com
docker pull registry.cn-hangzhou.aliyuncs.com/dfuttu/java-demo-01:1.0.0

image-20221115160508089

部署镜像

创建 yaml 文件

kubectl create deployment javademo1 --image=registry.cn-hangzhou.aliyuncs.com/dfuttu/java-demo-01:1.0.0 --dry-run -o yaml > javademo1.yaml

修改 replicas: 3(为了查看负载均衡)

image-20221115161726256

部署 deployment

kubectl apply -f javademo1.yaml 

查看 pods

kubectl get pods -o wide

image-20221115161707008

暴露应用

kubectl expose deployment javademo1 --port=8111 --target-port=8111 --type=NodePort

image-20221115161914077

浏览器访问 http://192.168.0.103:31201/user

image-20221115162133491

浏览器访问 http://192.168.0.104:31201/user

image-20221115162116149

posted @ 2023-03-17 10:07  dfuttu  阅读(76)  评论(0)    收藏  举报