K8S学习之K8S篇(一)
一. 梳理k8s 各组件功能
1. kube-apiserver
Kubernetes API 服务器验证并配置 API 对象的数据, 这些对象包括 pods、services、replicationcontrollers 等。 API 服务器为 REST 操作提供服务,并为集群的共享状态提供前端, 所有其他组件都通过该前端进行交互。
APIServer是集群管理API的统一入口
为了更好的理解这个概念可以看如下图

通过kubectl命令执行创建pod时,经历的流程如上图,大概流程为
- apiserver接收kubectl的创建资源的请求
- apiserver将创建请求写入ECTD
- apiserver接收到etcd的回调事件
- apiserver将回调事件发送给ControllerManager
- controllerManager中的ReplicationController处理本次请求,创建RS,然后它会调控RS中的Pod的副本数量处于期望值,比期望值小就新创建Pod,于是它告诉ApiServer要创建Pod
- apiserver将创建pod的请求写入etcd集群
- apiserver接收etcd的创建pod的回调事件
- apiserver将创建pod的回调事件发送给scheduler,由它为pod挑选一个合适的宿主node
- scheduler告诉apiserver,这个pod可以调度到哪个node上
- apiserver将scheduler告诉他的事件写入etcd
- apiserver接收到etcd的回调,将更新pod的事件发送给对应node上的kubelet进程
- kubelet通过CRI接口同容器运行时(Docker)交互,维护更新对应的容器。
2.Controll-Manager
kube-controller-manager 是负责运行 控制器 进程的组件。控制器可以通过 api-server 监控集群的公共状态,并尽力维持健康状态。从逻辑上讲,每个控制器 都是一个单独的进程, 但是为了降低复杂性,它们都被编译到同一个可执行文件,并在一个进程中运行
控制器包括:
节点控制器(Node Controller): 负责在节点出现故障时进行通知和响应
任务控制器(Job controller): 监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成
端点控制器(Endpoints Controller): 填充端点(Endpoints)对象(即加入 Service 与 Pod)
服务帐户和令牌控制器(Service Account & Token Controllers): 为新的命名空间创建默认帐户和 API 访问令牌
3. Kube-scheduler
该组件负责资源调度,如监视新创建的、未指定运行节点(node) 的 Pods, 并选择节点来让 Pod 在上面运行。
调度决策考虑的因素包括单个 Pod 及 Pods 集合的资源需求、软硬件及策略约束、 亲和性及反亲和性规范、数据位置、工作负载间的干扰等。
4. Etcd
etcd 是兼具一致性和高可用性的 key/value 类型的数据库,其保存了 Kubernetes 所有的集群数据,生产环境通常需要高可用部署,并做定时备份
etcd 集群可以在集成在控制面节点,也可以单独部署在其他机器节点
注:只有 kube-apiserver 组件会对 etcd 做数据操作,其他组件的数据操作都是通过调用 kube-apiserver 组件
5. Kube-proxy
组件运行在 K8s 集群中的每个 work 节点上,是集群中每个 work 节点上运行的网络代理,负责维护节点上的一些网络规则, 这些网络规则会允许从集群内部或外部的网络会话与 Pod 进行网络通信。
如果操作系统提供了可用的数据包过滤层,则 kube-proxy 会通过它来实现网络规则。 否则,kube-proxy 仅做流量转发。
6. Kubelet
kubelet 是在每个 Node 节点上运行的主要 “节点代理”,该组件运行在 K8s 集群中的每个 Node 节点上,保证容器都运行在 Pod 中
kubelet 是基于 PodSpec 来工作的。每个 PodSpec 是一个描述 Pod 的 YAML 或 JSON 对象。 kubelet 接受通过各种机制(主要是通过 apiserver)提供的一组 PodSpec,并确保这些 PodSpec 中描述的容器处于运行状态且运行状况良好。 kubelet 不会管理非 Kubernetes 创建的容器
除了来自 apiserver 的 PodSpec 之外,还可以通过以下两种方式将容器清单(manifest)提供给 kubelet
文件(File):利用命令行参数传递路径。kubelet 周期性地监视此路径下的文件是否有更新。 监视周期默认为 20s,且可通过参数进行配置
HTTP 端点(HTTP endpoint):利用命令行参数指定 HTTP 端点。 此端点的监视周期默认为 20 秒,也可以使用参数进行配置
二. 基本掌握containerd的安装和使用
1. 下载二进制文件
https://github.com/containerd/containerd
root@wang:~# tar -xf containerd-1.7.0-linux-amd64.tar.gz root@wang:~# cp bin/* /usr/bin/
2. 创建containerd.service 文件
root@wang:~# cat /usr/lib/systemd/system/containerd.service # Copyright The containerd Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. [Unit] Description=containerd container runtime Documentation=https://containerd.io After=network.target local-fs.target [Service] #uncomment to enable the experimental sbservice (sandboxed) version of containerd/cri integration #Environment="ENABLE_CRI_SANDBOXES=sandboxed" ExecStartPre=-/usr/bin/modprobe overlay ExecStart=/usr/bin/containerd Type=notify Delegate=yes KillMode=process Restart=always RestartSec=5 # Having non-zero Limit*s causes performance problems due to accounting overhead # in the kernel. We recommend using cgroups to do container-local accounting. LimitNPROC=infinity LimitCORE=infinity LimitNOFILE=infinity # Comment TasksMax if your systemd version does not supports it. # Only systemd 226 and above support this version. TasksMax=infinity OOMScoreAdjust=-999 [Install] WantedBy=multi-user.target
启动containerd
systemctl start containerd
3. 安装运行时runc
https://github.com/opencontainers/runc/releases
root@wang:~# cp runc.amd64 /usr/bin/runc root@wang:~# chmod 755 /usr/bin/runc
4. 从harbor上下载镜像,启动容器
root@wang:~# ctr images pull --skip-verify --user admin:123456 --plain-http 192.168.0.10/nginx/nginx:v1 192.168.0.10/nginx/nginx:v1: resolved |++++++++++++++++++++++++++++++++++++++| manifest-sha256:d139534475507d7eaf5ffd8aabf4c3be1b9918dfaa145aa42265513ec71c7ca6: done |++++++++++++++++++++++++++++++++++++++| config-sha256:291dfaf2c1b63fe325d9d0b7b06583c09c11cf9131cc45755263810f253abd35: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:b8917008ec5e5946656d2ca346b3a818620715f38db4c442445b369a974f91df: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:ce397af435f4d27f45fffe765cb7fdd63411d8df57e1a9ad104976c07bf99a56: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:1d122f17c3818d7a90fb8696547702599c1d34460653ffa5dea2b7824c3b7577: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:ac9208207adaac3a48e54a4dc6b49c69e78c3072d2b3add7efdabf814db2133b: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:6284171712e80dbe4cb34297cc736ecf36d7e5349b99967e5d930e0734cd9f90: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:58178ea368750dfb273992ddf1a3b60bb9ffd3c2230cbb40f4de6379d83c5535: done |++++++++++++++++++++++++++++++++++++++| elapsed: 2.6 s total: 130.7 (50.3 MiB/s) unpacking linux/amd64 sha256:d139534475507d7eaf5ffd8aabf4c3be1b9918dfaa145aa42265513ec71c7ca6... done: 6.683217394s
root@wang:~# ctr run -t --net-host 192.168.0.10/nginx/nginx:v1 container1 sh sh-4.2# ip a sh: ip: command not found sh-4.2# ifconfig sh: ifconfig: command not found sh-4.2# ping 192.168.0.1 PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data. 64 bytes from 192.168.0.1: icmp_seq=1 ttl=64 time=0.050 ms 64 bytes from 192.168.0.1: icmp_seq=2 ttl=64 time=0.048 ms
三. 基于kubeadm和containerd部署单master k8s v1.24.3
1. 安装cni插件
root@master001:~# wget https://github.com/containernetworking/plugins/releases/download/v1.2.0/cni-plugins-linux-amd64-v1.2.0.tgz
root@master001:~# mkdir /opt/cni/bin
root@master001:~#tar -xf cni-plugins-linux-amd64-v1.2.0.tgz -C /opt/cni/bin
2. 修改containerd配置文件
root@master001:~#t cat /etc/containerd/config.toml
61 sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.7"
153 [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
154 [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
3. 部署kubeadm
(1)开机启动br_netfilter模块
root@ecs-67093:~# cat << EOF >> /etc/rc.local
> #!/bin/bash
> modprobe br_netfilter
> EOF
root@ecs-67093:~# chmod a+x /etc/rc.local
root@ecs-67093:~# systemctl restart rc-local
root@ecs-67093:~# lsmod | grep br_netfilter
(2)优化内核参数
root@ecs-67093:~# cat << EOF >> /etc/sysctl.conf
> net.bridge.bridge-nf-call-iptables = 1 #容器启动后会创建网桥,内核监听网桥上有过的报文,以实现对报文的安全控制、规则检查,ingress、egress就是通过对报文的检查来决定允许通行或禁止通行
> net.bridge.bridge-nf-call-ip6tables = 1
> net.ipv4.ip_forward = 1 #把Linux当作路由器使用,使其具备路由功能,基于路由表做地址转发、报文转发、源地址替换等,否则无法跨主机通信
> EOF
root@ecs-67093:~# sysctl -p
2.安装kubeadm基础环境
(1)安装kubeadm、kubectl、kubelet
master上安装kubeadm、kubectl、kubelet;node上安装kubeadm、kubelet,kubectl可以不安装
root@ecs-67093:~# apt-get update && apt-get install -y apt-transport-https #支持https源
root@ecs-67093:~# curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add - #导入key
root@ecs-67093:~# cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
> deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
> EOF #配置源
root@ecs-67093:~# apt-get update
root@ecs-67093:~# apt-cache madison kubeadm
root@ecs-67093:~# apt-get install -y kubeadm=1.24.3-00 kubectl=1.24.3-00 kubelet=1.24.3-00
3.初始化kubernetes
(1)下载镜像
root@ecs-67093:~# kubeadm config images list --kubernetes-version v1.24.3 查看kubeadm初始化所需要的镜像
k8s.gcr.io/kube-apiserver:v1.24.3
k8s.gcr.io/kube-controller-manager:v1.24.3
k8s.gcr.io/kube-scheduler:v1.24.3
k8s.gcr.io/kube-proxy:v1.24.3
k8s.gcr.io/pause:3.7
k8s.gcr.io/etcd:3.5.3-0
k8s.gcr.io/coredns/coredns:v1.8.6
root@ecs-67093:~#kubeadm config images pull --kubernetes-version v1.24.3 --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers 通过阿里云的镜像源下载kubeadm初始化所需要的镜像
(2)初始化k8s集群
kubeadm init --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.24.3 --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.64.13

(3)配置认证文件
root@ecs-67093:~# mkdir -p $HOME/.kube
root@ecs-67093:~# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
root@ecs-67093:~# sudo chown $(id -u):$(id -g) $HOME/.kube/config
root@ecs-67093:~# kubectl get node

四. 部署harbor并实现https(SAN签发证书)
1、自签名CA机构
1、创建certs目录存放证书文件
root@harbor:/apps/harbor# mkdir /apps/harbor/certs
root@harbor:/apps/harbor# cd certs/
2、创建CA私钥
root@harbor:/apps/harbor/certs# openssl genrsa -out ca.key 4096
Generating RSA private key, 4096 bit long modulus (2 primes)
................................................++++
..............................++++
e is 65537 (0x010001)
3、自签发CA crt证书
root@harbor:/apps/harbor/certs# openssl req -x509 -new -nodes -sha512 -days 3650 \
> -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=magedu.com" \
> -key ca.key \
> -out ca.crt
root@harbor:/apps/harbor/certs# ll
total 16
drwxr-xr-x 2 root root 4096 Nov 7 11:52 ./
drwxr-xr-x 3 root root 4096 Nov 7 11:47 ../
-rw-r--r-- 1 root root 2041 Nov 7 11:52 ca.crt
-rw------- 1 root root 3247 Nov 7 11:48 ca.key
这样就签发好了一对密钥了,就可以用它们来给harbor来颁发证书了
#参数说明:
## C,Country,代表国家
## ST,STate,代表省份
## L,Location,代表城市
## O,Organization,代表组织,公司
## OU,Organization Unit,代表部门
## CN,Common Name,代表服务器域名
## emailAddress,代表联系人邮箱地址。
2、客户端私钥证书生成
root@harbor:/apps/harbor/certs# openssl genrsa -out magedu.net.key 4096
Generating RSA private key, 4096 bit long modulus (2 primes)
.....................................++++
.........................................++++
e is 65537 (0x010001)
root@harbor:/apps/harbor/certs# ls
ca.crt ca.key magedu.net.key
申请的这个magedu.net.key是给harbor用的magedu.net是harbor的域名
生成一个csr文件,但是这个文件暂时还不能使用
root@harbor:/apps/harbor/certs# openssl req -sha512 -new \
> -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=magedu.net" \
> -key magedu.net.key \
> -out magedu.net.csr
3、准备签发环境
签发SAN文件
生成一个ext文本文件,内容就是签发信息,把这些证书签发给哪些目标的域名
所以harbor的域名必须选择下面的三个域名,签发的证书只对下面三个域名有效
root@harbor:/apps/harbor/certs# cat > v3.ext <<-EOF
> authorityKeyIdentifier=keyid,issuer
> basicConstraints=CA:FALSE
> keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
> extendedKeyUsage = serverAuth
> subjectAltName = @alt_names
> [alt_names]
> DNS.1=magedu.com
> DNS.2=harbor.magedu.net
> DNS.3=harbor.magedu.local
> EOF
root@harbor:/apps/harbor/certs# ls
ca.crt ca.key magedu.net.key v3.ext
4、使用自签名CA签发证书
root@harbor:/apps/harbor/certs# openssl x509 -req -sha512 -days 3650 \
> -extfile v3.ext \
> -CA ca.crt -CAkey ca.key -CAcreateserial \
> -in magedu.net.csr \
> -out magedu.net.crt
Signature ok
subject=C = CN, ST = Beijing, L = Beijing, O = example, OU = Personal, CN = magedu.net
Getting CA Private Key
-CA ca.crt -CAkey ca.key表示CA直接签发,指定magedu.net.csr这个文件,
签发完后是magedu.net.crt文件;并会加载v3.ext这个文件,v3.ext文件的
信息会被签发到magedu.net.crt文件信息证书里
5. 修改harbor配置文件

6. 重启harbor
查看容器端口映射情况,可以看到宿主机的443端口被容器的8443端口映射。

使用浏览器通过https方式访问harbor

通过命令行login测试

浙公网安备 33010602011771号