第一部分:理解 K8s 原理
1.1 应用部署发展过程

- 传统物理机部署:软件直接装在服务器。缺点:资源没法限制,一个程序吃满 CPU 内存,会把别的程序搞崩。
- 虚拟机部署:一台物理机跑多台虚拟机,每台虚拟机独立操作系统。缺点:每台虚拟机完整装一套系统,特别吃内存硬盘,资源浪费大。
- 容器部署 (Docker) :多个容器共享宿主机操作系统内核,每个容器打包自己的程序和依赖,体积小、启动快。
问题来了:机器少手动启动容器还行;几十上百台服务器,成千上万个容器,手动管不过来:容器挂了怎么自动重启?访问量变大怎么自动多开容器?怎么把请求分发到多个容器? → 这就需要容器编排工具 K8s,专门帮我们批量管理容器。
答:这就需要容器编排工具 K8s,专门帮我们批量管理容器。
1.2 K8s 集群两大角色(控制节点 + 工作节点)

整个 K8s 集群分成两类机器:
Master 控制节点(做决策,不跑业务程序)
- apiserver:整个集群唯一入口,所有操作(创建 / 删除应用)都找它,做身份校验,读写集群数据。
- etcd:集群数据库,存全部集群信息:有多少机器、有多少容器、配置是什么。
- scheduler 调度器:新的容器该放到哪台 worker 机器上跑,它来选机器。
- controller‑manager 控制器:盯着集群状态,如果容器挂了,就命令重新拉起,保证符合你的预期。
Node 工作节点(干活,真正跑业务容器)
- kubelet:每台 worker 机器上的代理,接收 master 大脑下发指令,管理本机容器生命周期。
- 容器运行时 :真正创建、启动容器的软件,本实验用 Docker,因为 k8s1.24 之后不再原生支持 docker,必须装
cri‑dockerd适配器做中转。 - kube‑proxy:网络代理,负责服务发现、负载均衡,外部访问业务的时候转发流量。
最小单元叫Pod :Pod 是 k8s 最小单元,一个 Pod 里面可以放 1 个或者多个容器,同一个 Pod 容器共享网络、共享存储。平时我们部署应用本质是部署 Pod。
1.3 为什么我们要部署 Harbor 私有镜像仓库?
镜像就是容器安装包。默认镜像要去外网下载,实验室环境外网慢甚至不通。
Harbor 就是本地局域网的镜像仓库服务器:把所有 k8s 需要的组件镜像下载下来传到 harbor,所有 k8s 机器从内网拉镜像,速度飞快。
1.4 为什么要用 cri‑dockerd?
K8s 1.24 版本开始官方抛弃 dockershim,不再原生对接 Docker。
Docker 本身不能直接被 k8s 调用。cri‑dockerd就是一个 "翻译适配器":k8s 发标准 CRI 接口指令,适配器转成 Docker 能听懂的指令,让 Docker 继续作为容器运行时。
1.5 网络插件 Flannel 是干嘛的?
刚初始化完 k8s 集群,节点状态是NotReady没准备好。
因为 k8s 需要一套网络:不同机器上 Pod 之间要互相通信。Flannel 就是网络插件,搭建集群内部网络,装好之后节点状态变成 Ready。
1.6 必做环境预处理,为什么?
- 关闭 swap 交换分区:swap 是硬盘虚拟内存。k8s 不允许开启 swap,内存不够宁愿把容器杀掉也不用硬盘虚拟内存,会影响调度性能。
- 内核参数开启网桥转发:容器之间网络互通,需要开启内核 iptables 转发。
- 主机解析 /etc/hosts:各个机器通过域名能互相找到,不用记复杂 IP。
第二部分:完整实验部署
集群规划:
| 主机名 | ip | 配置 | 角色 |
|---|---|---|---|
| harbor | 172.25.254.200 | cpu2、mem 2G | harbor仓库 |
| master | 172.25.254.150 | cpu4、mem>4G | master,k8s集群控制节点 |
| node1 | 172.25.254.30 | cpu2、mem 2G | worker,k8s集群工作节点 |
| node2 | 172.25.254.40 | cpu2、mem 2G | worker,k8s集群工作节点 |
步骤一:部署 Harbor 服务器
1.1 制作本地 docker yum 源
root@harbor \~# cat > /etc/yum.repos.d/docker.repo <<EOF
docker
name = docker
baseurl = https://mirrors.aliyun.com/docker-ce/linux/rhel/9.6/x86_64/stable/
gpgcheck = 0
EOF
root@harbor \~# dnf install httpd createrepo -y
root@harbor \~# mkdir /var/www/html/docker/ -p
root@harbor \~# vim /etc/httpd/conf/httpd.conf

root@harbor \~# systemctl enable --now httpd
root@harbor \~# dnf install docker-ce --downloadonly --destdir /mnt/ -y
root@harbor \~# mv /mnt/*.rpm /var/www/html/docker/
root@harbor \~# createrepo -v /var/www/html/docker/
root@harbor \~# cat > /etc/yum.repos.d/docker.repo <<EOF
docker
name = docker
baseurl = http://172.25.254.200:4444/docker
gpgcheck = 0
EOF
1.2 Harbor 节点配置 docker 和内核参数
root@harbor \~# dnf install docker-ce -y
root@harbor \~# echo br_netfilter > /etc/modules-load.d/docker_mod.conf
root@harbor \~# modprobe -a br_netfilter
root@harbor \~# vim /etc/sysctl.d/docker.conf

root@harbor \~# systemctl restart systemd-modules-load.service
root@harbor \~# sysctl --system
root@harbor \~# vim /lib/systemd/system/docker.service

root@harbor \~# systemctl daemon-reload
root@harbor \~# systemctl enable --now docker
1.3 生成自签名证书
root@harbor \~# mkdir /data/certs -p
root@harbor \~# openssl req -newkey rsa:4096 \
-nodes -sha256 -keyout /data/certs/timinglee.org.key \
-addext "subjectAltName = DNS:reg.timinglee.org" \
-x509 -days 365 -out /data/certs/timinglee.org.crt

1.4 解压配置 Harbor
root@harbor \~# tar zxf harbor-offline-installer-v2.5.4.tgz -C /opt/
root@harbor \~# cd /opt/harbor/

root@harbor harbor# cp harbor.yml.tmpl harbor.yml
root@harbor harbor# vim harbor.yml

root@harbor harbor# ./install.sh --with-chartmuseum
1.5 设置 harbor 为 systemd 服务管理
root@harbor harbor# vim /lib/systemd/system/harbor.service

root@harbor harbor# systemctl daemon-reload
root@harbor harbor# systemctl enable --now harbor
root@harbor harbor# docker compose up
root@harbor harbor# docker compose down

1.6 docker 信任 harbor 证书
root@harbor harbor# mkdir /etc/docker/certs.d/reg.timinglee.org/ -p
root@harbor harbor# cp /data/certs/timinglee.org.crt /etc/docker/certs.d/reg.timinglee.org/ca.crt
root@harbor harbor# vim /etc/hosts

root@harbor harbor# systemctl restart docker

步骤二:所有 k8s 节点统一环境配置
2.1 所有主机彻底关闭 swap 分区
以harbor为例:
root@harbor harbor# sed '/swap/s/^/#/g' -i /etc/fstab
root@harbor harbor# reboot

2.2 所有节点配置 /etc/hosts 主机解析
root@harbor \~# vim /etc/hosts
root@harbor \~# for i in 150 30 40
> do
> scp /etc/hosts root@172.25.254.$i:/etc/hosts
> done
步骤三:利用Ansible部署kubernetes运行环境
3.1 安装ansible
root@harbor \~# vim /etc/yum.repos.d/epel.repo

root@harbor \~# dnf install ansible-core.x86_64 ansible.noarch -y
3.2 配置所需用户
root@harbor \~# useradd devops
root@harbor \~# echo lee | passwd --stdin devops
root@harbor \~# su - devops
devops@harbor \~$ mkdir ansible
devops@harbor \~$ cd ansible/
devops@harbor ansible$
3.3 生成ansible的临时配置文件并建立运行环境
devops@harbor ansible$ vim inventory

devops@harbor ansible$ vim ansible.cfg


#建立用户
devops@harbor ansible$ ansible all -m user -a "name=devops state=present"
devops@harbor ansible$ ansible all -m shell -a 'echo "lee" | passwd --stdin devops'
devops@harbor ansible$ ansible all -m lineinfile -a 'path=/etc/sudoers line="devops ALL=(ALL) NOPASSWD: ALL" insertafter=EOF'
3.4生成ansible的主配置文件并测试
devops@harbor ansible$ vim ansible.cfg

测试:

3.5 利用ansible剧本部署docker
#关闭防火墙
root@harbor \~# systemctl disable --now firewalld.service
Removed "/etc/systemd/system/multi-user.target.wants/firewalld.service".
Removed "/etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service".
devops@harbor ansible$ su -
密码:
root@harbor \~# cp /opt/harbor/common/config/registry/root.crt /home/devops/ansible/ca.crt
root@harbor \~# chown devops:devops /home/devops/ansible/ca.crt
root@harbor \~# exit
注销
devops@harbor ansible$ ls -l /home/devops/ansible/ca.crt
-rw-r--r-- 1 devops devops 0 8月 22 19:55 /home/devops/ansible/ca.crt
devops@harbor ansible$ vim kubernetes-devops.yml
- name: devops k8s from ansible
hosts: all
become: true
gather_facts: true
tasks:
- name: setup docker repo
yum_repository:
name: docker
description: docker
baseurl: http://172.25.254.200:4444/docker
file: docker
gpgcheck: no
- name: install docker
dnf:
name: docker-ce
state: present
- name: modify docker.service ExecStart
replace:
path: /lib/systemd/system/docker.service
regexp: '^(ExecStart=/usr/bin/dockerd.*)$'
replace: 'ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --iptables=true'
backup: yes
- name: systemctl daemon‑reload after docker.service change
systemd:
daemon_reload: yes
- name: setup docker registry daemon.json
copy:
content: |
{
"registry-mirrors":"https://reg.timinglee.org"
}
dest: /etc/docker/daemon.json
mode: '0644'
- name: create docker cert directory
file:
path: /etc/docker/certs.d/reg.timinglee.org
state: directory
mode: '0755'
- name: copy harbor ca certificate
copy:
src: "./ca.crt"
dest: "{{ item.dest }}"
loop:
-
{ dest: "/etc/docker/certs.d/reg.timinglee.org/ca.crt" }
-
{ dest: "/etc/pki/ca-trust/source/anchors/ca.crt" }
-
name: load kernel module br_netfilter config
copy:
dest: "{{ item.dest }}"
content: "{{ item.value }}"
loop:
- dest: /etc/modules-load.d/docker_mod.conf
value: br_netfilter
- dest: /etc/sysctl.d/docker.conf
value: |
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
- name: load br_netfilter kernel module
community.general.modprobe:
name: br_netfilter
state: present
- name: refresh ca trust & reload sysctl
shell: update-ca-trust extract; sysctl --system
changed_when: false
- name: start and enable services
service:
name: "{{ item }}"
state: restarted
enabled: yes
loop:
-
docker
-
systemd-modules-load.service
devops@harbor ansible$ ansible-playbook kubernetes-devops.yml
3.6 利用ansible安装cri-dockerd
devops@harbor ansible$ tar zxf cri-dockerd-0.4.4.amd64.tgz

devops@harbor ansible$ cd cri-dockerd/

devops@harbor cri-dockerd$ vim cri-docker.service

devops@harbor ansible$ vim kubernetes-devops.yml
- name: devops k8s from ansible
hosts: all
tasks:
- name: setup docker repo
yum_repository:
name: docker
description: docker
baseurl: http://172.25.254.200:4444/docker
file: docker
gpgcheck: no
- name: install docker
dnf:
name: docker-ce
state: present
- name: setup docker.service
replace:
path: /lib/systemd/system/docker.service
regexp: "ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock"
replace: "ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --iptables=true"
- name: setup docker registry
copy:
content: |
{
"registry-mirrors":"https://reg.timinglee.org"
}
dest: /etc/docker/daemon.json
- name: setup docker certs
file:
path: /etc/docker/certs.d/reg.timinglee.org
state: directory
- name: cp certs file
copy:
src: "{{item.src}}"
dest: "{{item.dest}}"
loop:
- src: /etc/docker/certs.d/reg.timinglee.org/ca.crt
dest: /etc/docker/certs.d/reg.timinglee.org/ca.crt
- src: /etc/docker/certs.d/reg.timinglee.org/ca.crt
dest: /etc/pki/ca-trust/source/anchors/ca.crt
########################################################
- name: stup cri-dockerd
copy:
src: "{{item.src}}"
dest: "{{item.dest}}"
mode: '0755'
loop:
- src: ./cri-dockerd/cri-dockerd
dest: /usr/bin/cri-dockerd
- src: "./cri-dockerd/cri-docker.service"
dest: "/lib/systemd/system/cri-docker.service"
- src: "./cri-dockerd/cri-docker.socket"
dest: "/lib/systemd/system/cri-docker.socket"
- name: update ca cert
shell: "update-ca-trust extract;sysctl --system;systemctl daemon-reload"
- name: start services
service:
name: "{{item}}"
state: restarted
enabled: yes
loop:
-
docker
-
systemd-modules-load.service
-
cri-docker
devops@harbor ansible$ ansible-playbook kubernetes-devops.yml
3.7 利用ansible部署k8s软件
devops@harbor ansible$ mv kubernetes-devops.yml docker-devops.yml
devops@harbor ansible$ vim kubernetes-devops.yml
- name: install kubernetes from ansible
hosts: all
tasks:
- name: setup k8s repo
yum_repository:
name: kubernetes
description: kubernetes
baseurl: https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.35/rpm
file: kubernetes
gpgcheck: no
- name: install software in master
dnf:
name: "{{item}}"
state: present
loop:
-
kubeadm-1.35.7-150500.1.1
-
kubelet-1.35.7-150500.1.1
-
kubectl-1.35.7-150500.1.1
when: inventory_hostname == "172.25.254.150"
- name: install software in work node
dnf:
name: "{{item}}"
state: present
loop:
-
kubeadm-1.35.7-150500.1.1
-
kubelet-1.35.7-150500.1.1
when: inventory_hostname == "172.25.254.30" or inventory_hostname == "172.25.254.40"
- name: setup kubectl kubeadm complication
lineinfile:
path: /root/.bashrc
line: |
source <(kubectl completion bash)
source <(kubeadm completion bash)
when: inventory_hostname == "172.25.254.150"
- name: start kubelet
service:
name: kubelet
state: started
enabled: yes
devops@harbor ansible$ ansible-playbook kubernetes-devops.yml
#让补齐功能生效
root@master \~# source ~/.bashrc
root@master \~# kubectl 命令后按2此tab键
alpha (Commands for features in alpha)
annotate (更新一个资源的注解)
api-resources (Print the supported API resources on the server)
api-versions (Print the supported API versions on the server, in the form of "group/version")
apply (Apply a configuration to a resource by file name or stdin)
attach (挂接到一个运行中的容器)
auth (Inspect authorization)
autoscale (Auto-scale a deployment, replica set, stateful set, or replication controller)
certificate (Modify certificate resources)
root@master \~# kubeadm

