k8s集群部署的方法
一.构建harbor镜像仓库
1.部署docker本地仓库
[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
Listen 4444
[root@harbor ~]# systemctl enable --now httpd
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.
[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/
12:10:16: Version: 0.20.1 (Features: LegacyWeakdeps )
12:10:16: Signal handler setup
12:10:16: Thread pool ready
Directory walk started
12:10:16: Adding pkg: /var/www/html/docker/containerd.io-2.3.3-1.el9.x86_64.rpm
12:10:16: Adding pkg: /var/www/html/docker/docker-buildx-plugin-0.36.1-1.el9.x86_64.rpm
12:10:16: Adding pkg: /var/www/html/docker/docker-ce-29.7.2-1.el9.x86_64.rpm
12:10:16: Adding pkg: /var/www/html/docker/docker-ce-cli-29.7.2-1.el9.x86_64.rpm
12:10:16: Adding pkg: /var/www/html/docker/docker-ce-rootless-extras-29.7.2-1.el9.x86_64.rpm
12:10:16: Adding pkg: /var/www/html/docker/docker-compose-plugin-5.5.0-1.el9.x86_64.rpm
12:10:16: Dir to scan: /var/www/html/docker/.repodata
12:10:16: Package count: 6
Directory walk done - 6 packages
Temporary output repo path: /var/www/html/docker/.repodata/
12:10:16: Creating .xml.gz files
12:10:16: Setting number of packages
Preparing sqlite DBs
12:10:16: Creating databases
12:10:16: Thread pool user data ready
Pool started (with 5 workers)
Pool finished
12:10:16: Generating repomd.xml
12:10:16: Old repodata doesn't exists: Cannot rename /var/www/html/docker/repodata/ -> /var/www/html/docker/repodata.old.33377.20260822121016.888003: cp: ????'/var/www/html/docker/repodata/' ?????(stat): ????????? : Child process exited with code 1
12:10:16: Renamed /var/www/html/docker/.repodata/ -> /var/www/html/docker/repodata/
12:10:16: Memory cleanup
12:10:16: All done
[root@harbor ~]# vim /etc/yum.repos.d/docker.repo
[docker]
name = docker
baseurl = http://172.25.254.250:4444/docker
gpgcheck = 0
2.安装docker在harbor仓库节点
[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
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
[root@harbor ~]# systemctl restart systemd-modules-load.service
[root@harbor ~]# sysctl --system
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
[root@harbor ~]# vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --iptables=true
[root@harbor ~]# systemctl daemon-reload
[root@harbor ~]# systemctl enable --now docker
Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /usr/lib/systemd/system/docker.service.
3.生成key
[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
.+.+...+..+...+................+..+..................+......+.+++++++++++++++++++++++++++++++++++++++++++++*....+.....+...+...+...+......+.+........+..........+.....+....+..+...+..........+.....+.......+.........+..+.............+...............+......+......+..+++++++++++++++++++++++++++++++++++++++++++++*...+.............+..+......+.....................+.+.................................+..............+.+.........+...+...............+...+...........+.+..+......+............+...+...............+................+...+...............+.....+...+....+.....+.+...+...............+.....+....+..+.........+.......+...............+.....+...............+....+.........+......+......+........+......+................+........+..........+...........+....+.........+..+................+..+......+.+......+...+.....+......+...+.+......+......+.........+...+...........+....+..+.+..+...+.........+...+......+.........+......+.+...+..+++++
....+.....+.+......+.....+....+.....+...+...+.........+.+...+.........+...+..+.......+...............+...+......+.....+......+..........+......+...+..+...+.........+...+...+.+...+...+............+..+...+.......+...+......+..+...+.+........+...+...+......+.+..+.+......+.....+...+.+++++++++++++++++++++++++++++++++++++++++++++*..+++++++++++++++++++++++++++++++++++++++++++++*.+....+...+.....+................+.........+.....................+.....+.+...+..+.+...............+........+...........................+....+...+...+..+.+..+.......+..+...+............+...+..................+...+.+...+......+..+..........+...+...............+.........+.....+..........+..+...+......+.+........+......+.......+.............................+++++
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Shannxi
Locality Name (eg, city) [Default City]:Xi'an
Organization Name (eg, company) [Default Company Ltd]:kubernetes
Organizational Unit Name (eg, section) []:harbor
Common Name (eg, your name or your server's hostname) []:reg.timinglee.org
Email Address []:admin@timinglee.org
4.编辑harbor配置文件
[root@harbor ~]# rm -rf haproxy-2.3.tar.gz
[root@harbor ~]# ls
公共 模板 视频 图片 文档 下载 音乐 桌面 anaconda-ks.cfg harbor-offline-installer-v2.5.4.tgz
[root@harbor ~]# tar zxf harbor-offline-installer-v2.5.4.tgz -C /opt/
[root@harbor ~]# cd /opt/harbor/
[root@harbor harbor]# ls
common.sh harbor.v2.5.4.tar.gz harbor.yml.tmpl install.sh LICENSE prepare
[root@harbor harbor]# cp harbor.yml.tmpl harbor.yml
[root@harbor harbor]# vim harbor.yml
# Configuration file of Harbor
# The IP address or hostname to access admin UI and registry service.
# DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
hostname: reg.timinglee.org
# http related config
http:
# port for http, default is 80. If https enabled, this port will redirect to https port
port: 80
# https related config
https:
# https port for harbor, default is 443
port: 443
# The path of cert and key files for nginx
certificate: /data/certs/timinglee.org.crt
private_key: /data/certs/timinglee.org.key
# # Uncomment following will enable tls communication between all harbor components
# internal_tls:
# # set enabled to true means internal tls is enabled
# enabled: true
# # put your cert and key files on dir
# dir: /etc/harbor/tls/internal
# Uncomment external_url if you want to enable external proxy
# And when it enabled the hostname will no longer used
# external_url: https://reg.mydomain.com:8433
# The initial password of Harbor admin
# It only works in first time to install harbor
# Remember Change the admin password from UI after launching Harbor.
harbor_admin_password: lee
[root@harbor harbor]# ./install.sh --with-chartmuseum
[root@harbor ~]# vim /lib/systemd/system/harbor.service
[Unit]
Description=harbor with Docker Compose
Documentation=https://reg.timinglee.com/compose/
After=docker.service network-online.target
Requires=docker.service
[Service]
Type=oneshot
WorkingDirectory=/opt/harbor
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
[root@harbor harbor]# docker compose down
WARN[0000] /opt/harbor/docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion
[+] down 12/12
✔ Container harbor-jobservice Removed 0.2s
✔ Container nginx Removed 0.3s
✔ Container chartmuseum Removed 0.2s
✔ Container registryctl Removed 10.2s
✔ Container harbor-portal Removed 0.2s
✔ Container harbor-core Removed 3.2s
✔ Container registry Removed 0.1s
✔ Container redis Removed 0.3s
✔ Container harbor-db Removed 0.2s
✔ Container harbor-log Removed 10.2s
✔ Network harbor_harbor-chartmuseum Removed 0.1s
✔ Network harbor_harbor Removed 0.1s
[root@harbor harbor]# cd
[root@harbor ~]# systemctl enable --now harbor
Created symlink /etc/systemd/system/multi-user.target.wants/harbor.service → /usr/lib/systemd/system/harbor.service.
[root@harbor ~]# cd /opt/harbor/
[root@harbor harbor]# docker compose ps
WARN[0000] /opt/harbor/docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
chartmuseum goharbor/chartmuseum-photon:v2.5.4 "./docker-entrypoint..." chartmuseum 26 seconds ago Up 25 seconds (health: starting)
harbor-core goharbor/harbor-core:v2.5.4 "/harbor/entrypoint...." core 26 seconds ago Up 25 seconds (health: starting)
harbor-db goharbor/harbor-db:v2.5.4 "/docker-entrypoint...." postgresql 26 seconds ago Up 25 seconds (health: starting)
harbor-jobservice goharbor/harbor-jobservice:v2.5.4 "/harbor/entrypoint...." jobservice 26 seconds ago Up 24 seconds (health: starting)
harbor-log goharbor/harbor-log:v2.5.4 "/bin/sh -c /usr/loc..." log 26 seconds ago Up 25 seconds (health: starting) 127.0.0.1:1514->10514/tcp
harbor-portal goharbor/harbor-portal:v2.5.4 "nginx -g 'daemon of..." portal 26 seconds ago Up 25 seconds (health: starting)
nginx goharbor/nginx-photon:v2.5.4 "nginx -g 'daemon of..." proxy 26 seconds ago Up 24 seconds (health: starting) 0.0.0.0:80->8080/tcp, [::]:80->8080/tcp, 0.0.0.0:443->8443/tcp, [::]:443->8443/tcp
redis goharbor/redis-photon:v2.5.4 "redis-server /etc/r..." redis 26 seconds ago Up 25 seconds (health: starting)
registry goharbor/registry-photon:v2.5.4 "/home/harbor/entryp..." registry 26 seconds ago Up 25 seconds (health: starting)
registryctl goharbor/harbor-registryctl:v2.5.4 "/home/harbor/start...." registryctl 26 seconds ago Up 25 seconds (health: starting)
5.启动并验证
[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
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.254.250 harbor reg.timinglee.org
[root@harbor harbor]# systemctl restart docker
[root@harbor harbor]# docker compose up -d
WARN[0000] /opt/harbor/docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion
[+] up 10/10
✔ Container harbor-core Running 0.0s
✔ Container registryctl Running 0.0s
✔ Container nginx Running 0.0s
✔ Container harbor-portal Running 0.0s
✔ Container harbor-log Running 0.0s
✔ Container harbor-db Running 0.0s
✔ Container chartmuseum Running 0.0s
✔ Container harbor-jobservice Running 0.0s
✔ Container registry Running 0.0s
✔ Container redis Running 0.0s
[root@harbor harbor]# docker login reg.timinglee.org -u admin
Password:
WARNING! Your credentials are stored unencrypted in '/root/.docker/config.json'.
Configure a credential helper to remove this warning. See
https://docs.docker.com/go/credential-store/
Login Succeeded
二.构建部署kubernetes所需主机
| 主机名 | ip | 配置 | 角色 |
|---|---|---|---|
| harbor.timinglee.org | 172.25.254.250 | cpu1、mem1G | harbor仓库 |
| master | 172.25.254.100 | cpu4、mem>4G | master,k8s集群控制节点 |
| node1 | 172.25.254.10 | cpu2、mem2G | worker、k8s集群控制节点 |
| node2 | 172.25.254.20 | cpu2、mem 2G | worker,k8s集群工作节点 |
所有主机配置
关闭swap
systemctl disable --now swap.target
systemctl mask swap.target
sed '/swap/s/^/#/g' -i /etc/fstab
安装docker
在新的机子上做
[root@master ~]# cat > /etc/yum.repos.d/docker.repo <<EOF
[docker]
name = docker
baseurl = http://172.25.254.250:4444/docker
gpgcheck = 0
EOF
[root@master ~]# dnf install docker-ce -y
[root@master ~]# echo br_netfilter > /etc/modules-load.d/docker_mod.conf
[root@master ~]# modprobe -a br_netfilter
[root@master ~]# vim /etc/sysctl.d/docker.conf
[root@master ~]# systemctl restart systemd-modules-load.service
[root@master ~]# sysctl --system
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
[root@harbor ~]# vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --iptables=true
[root@harbor ~]# systemctl daemon-reload
[root@harbor ~]# systemctl enable --now docker
配置可以使用harbor仓库
mkdir /etc/docker/certs.d/reg.timinglee.org/ -p
#在harbor主机中分发证书到所有主机
[root@harbor ~]# for i in 100 10 20
> do
> scp /data/certs/timinglee.org.crt root@172.25.254.$i:/etc/docker/certs.d/reg.timinglee.org/ca.crt
> done
systemctl enable docker
systemctl restart docker
所有主机配置docker加速器
cat >/etc/docker/daemon.json <<EOF
{
"registry-mirrors":["https://reg.timinglee.org"]
}
EOF
systemctl restart docker
docker info
可以看到
Registry Mirrors:
https://reg.timinglee.org/
所有主机彼此建立解析
vim /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.254.100 master
172.25.254.10 node1
172.25.254.20 node2
172.25.254.250 reg.timinglee.org
所有主机配置kubernetes安装源
vim /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name = kubernetes
baseurl = https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.35/rpm/
gpgcheck = 0
#检测
dnf list kubelet
reboot
swapon -s 没有任何输出表示ok
三.kubernetes的部署
利用Ansible部署kubernetes运行环境
1.安装ansible
[root@harbor ~]# vim /etc/yum.repos.d/epel.repo
[epel]
name = epel
baseurl = https://mirrors.aliyun.com/epel/9/Everything/x86_64/
gpgcheck = 0
[root@harbor ~]# dnf install ansible-core.x86_64 ansible.noarch -y
2.配置所需用户
[root@harbor ~]# useradd devops
[root@harbor ~]# echo lee | passwd --stdin devops
更改用户 devops 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@harbor ~]# su - devops
[devops@harbor ~]$ mkdir ansible
[devops@harbor ~]$ cd ansible/
[devops@harbor ansible]$
3.生成ansible的临时配置文件并建立运行环境
[devops@harbor ansible]$ vim inventory
[servers]
172.25.254.100
172.25.254.20
172.25.254.10
[devops@harbor ansible]$ vim ansible.cfg
[defaults]
inventory = /home/devops/ansible/inventory
remote_user = root
ask_pass = false
host_key_checking = false
[devops@harbor ansible]$ vim ansible.cfg
[defaults]
inventory = /home/devops/ansible/inventory
remote_user = root
ask_pass = false
host_key_checking = false
[devops@harbor ansible]$ ssh-keygen
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/devops/.ssh/id_ed25519):
Enter passphrase for "/home/devops/.ssh/id_ed25519" (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/devops/.ssh/id_ed25519
Your public key has been saved in /home/devops/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:rum5aTyEBFFVNBm3A/B2x8JA0jVRbPwZ0Gl8k3Y5eAU devops@harbor
The key's randomart image is:
+--[ED25519 256]--+
| .o..+*O+==o+Eo=|
| . oo* ++.*Bo|
| . o *.ooo++|
| . . . + o |
| . . S |
| . .. |
| o . |
| += |
| oBo |
+----[SHA256]-----+
[devops@harbor ansible]$ ssh-copy-id root@172.25.254.100
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/devops/.ssh/id_ed25519.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@172.25.254.100's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@172.25.254.100'"
and check to make sure that only the key(s) you wanted were added.
[devops@harbor ansible]$ ssh-copy-id root@172.25.254.10
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/devops/.ssh/id_ed25519.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@172.25.254.10's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@172.25.254.10'"
and check to make sure that only the key(s) you wanted were added.
[devops@harbor ansible]$ ssh-copy-id root@172.25.254.20
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/devops/.ssh/id_ed25519.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@172.25.254.20's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@172.25.254.20'"
and check to make sure that only the key(s) you wanted were added.
[devops@harbor ansible]$ ansible all -m ping
172.25.254.20 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
172.25.254.100 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
172.25.254.10 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
[devops@harbor ansible]$ ansible all -m user -a "name=devops state=present"
172.25.254.10 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"comment": "",
"create_home": true,
"group": 1001,
"home": "/home/devops",
"name": "devops",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 1001
}
172.25.254.20 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"comment": "",
"create_home": true,
"group": 1001,
"home": "/home/devops",
"name": "devops",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 1001
}
172.25.254.100 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"comment": "",
"create_home": true,
"group": 1001,
"home": "/home/devops",
"name": "devops",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 1001
}
[devops@harbor ansible]$ ansible all -m shell -a 'echo "lee" | passwd --stdin devops'
172.25.254.20 | CHANGED | rc=0 >>
更改用户 devops 的密码 。
passwd:所有的身份验证令牌已经成功更新。
172.25.254.10 | CHANGED | rc=0 >>
更改用户 devops 的密码 。
passwd:所有的身份验证令牌已经成功更新。
172.25.254.100 | CHANGED | rc=0 >>
更改用户 devops 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[devops@harbor ansible]$ ansible all -m lineinfile -a 'path=/etc/sudoers line="devops ALL=(ALL) NOPASSWD: ALL" insertafter=EOF'
172.25.254.10 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"backup": "",
"changed": true,
"msg": "line added"
}
172.25.254.20 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"backup": "",
"changed": true,
"msg": "line added"
}
172.25.254.100 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"backup": "",
"changed": true,
"msg": "line added"
}
4.生成ansible的主配置文件并测试
[devops@harbor ansible]$ vim ansible.cfg
[defaults]
inventory = /home/devops/ansible/inventory
remote_user = devops
ask_pass = false
host_key_checking = false
[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false
[devops@harbor ansible]$ ansible all -m shell -a 'whoami '
172.25.254.20 | CHANGED | rc=0 >>
root
172.25.254.10 | CHANGED | rc=0 >>
root
172.25.254.100 | CHANGED | rc=0 >>
root
5.利用ansible剧本部署docker
[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.254: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}}"
remote_src: yes
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: load module
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: update ca cert
shell: "update-ca-trust extract;sysctl --system"
changed_when: false
- name: start services
service:
name: "{{item}}"
state: restarted
enabled: yes
loop:
- docker
- systemd-modules-load.service
[devops@harbor ansible]$ ansible-playbook kubernetes-devops.yml
6.利用ansible安装cri-dockerd
[root@harbor ~]# ls
公共 图片 音乐 cri-dockerd-0.4.4.amd64.tgz
模板 文档 桌面 harbor-offline-installer-v2.5.4.tgz
视频 下载 anaconda-ks.cfg
[root@harbor ~]# cp /root/cri-dockerd-0.4.4.amd64.tgz /home/devops/ansible/
[root@harbor ~]# chown devops:devops /home/devops/ansible/cri-dockerd-0.4.4.amd64.tgz
[root@harbor ~]# su - devops
[devops@harbor ~]$ cd ansible/
[devops@harbor ansible]$ ls
ansible.cfg cri-dockerd-0.4.4.amd64.tgz inventory kubernetes-devops.yml
[devops@harbor ansible]$ tar zxf cri-dockerd-0.4.4.amd64.tgz
[devops@harbor ansible]$ cd cri-dockerd/
[devops@harbor cri-dockerd]$ ls
cri-dockerd cri-docker.service cri-docker.socket
[devops@harbor cri-dockerd]$ vim cri-docker.service
[Service]
Type=notify
ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --network-plugin=cni --pod-infra-container-image=reg.timinglee.org/k8s/pause:3.10.1
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
[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.254: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
[root@master ~]# vim /lib/systemd/system/cri-docker.service
[Service]
Type=notify
ExecStart=/usr/local/bin/cri-dockerd --network-plugin=cni --pod-infra-container-image=reg.timinglee.org/k8s/pause:3.10.1 --container-runtime-endpoint fd://
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
[root@master ~]# systemctl daemon-reload
[root@node1 ~]# systemctl restart cri-docker
7.利用ansible部署k8s软件
#将下面内容继续添加到文件里
[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.100"
- 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.10" or inventory_hostname == "172.25.254.20"
- name: setup kubectl kubeadm complication
lineinfile:
path: /root/.bashrc
line: |
source <(kubectl completion bash)
source <(kubeadm completion bash)
when: inventory_hostname == "172.25.254.100"
- name: start kubelet
service:
name: kubelet
state: started
enabled: yes
[devops@harbor ansible]$ ansible-playbook kubernetes-devops.yml
让补齐功能生效
[root@k8s-master mnt]# source ~/.bashrc
[root@k8s-master mnt]# 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@k8s-master mnt] # kubeadm
certs config init kubeconfig token version
completion help join reset upgrade
[root@master mnt]# systemctl status kubelet.service
● kubelet.service - kubelet: The Kubernetes Node Agent
Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; preset: disabled)
Drop-In: /usr/lib/systemd/system/kubelet.service.d
└─10-kubeadm.conf
Active: activating (auto-restart) (Result: exit-code) since Sat 2026-08-22 14:47:35 CST; 6s ago
Docs: https://kubernetes.io/docs/
Process: 20443 ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUB>
Main PID: 20443 (code=exited, status=1/FAILURE)
CPU: 23ms
8月 22 14:47:35 master systemd[1]: kubelet.service: Main process exited, code=exited, status=1/FAILURE
8月 22 14:47:35 master systemd[1]: kubelet.service: Failed with result 'exit-code'.
lines 1-12/12 (END)
在master中初始化kubernetes集群
在master中完成集群初始化
[root@master ~]# kubeadm config images list
I0822 15:08:36.584592 3162 version.go:260] remote version is much newer: v1.36.4; falling back to: stable-1.35
registry.k8s.io/kube-apiserver:v1.35.8
registry.k8s.io/kube-controller-manager:v1.35.8
registry.k8s.io/kube-scheduler:v1.35.8
registry.k8s.io/kube-proxy:v1.35.8
registry.k8s.io/coredns/coredns:v1.13.1
registry.k8s.io/pause:3.10.1
registry.k8s.io/etcd:3.6.6-0
[root@master ~]# kubeadm config images pull \
> --image-repository registry.aliyuncs.com/google_containers \
> --kubernetes-version v1.35.8 \
> --cri-socket=unix:///var/run/cri-dockerd.sock
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-apiserver:v1.35.8
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-controller-manager:v1.35.8
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-scheduler:v1.35.8
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-proxy:v1.35.8
[config/images] Pulled registry.aliyuncs.com/google_containers/coredns:v1.13.1
[config/images] Pulled registry.aliyuncs.com/google_containers/pause:3.10.1
[config/images] Pulled registry.aliyuncs.com/google_containers/etcd:3.6.6-0
[root@master ~]# docker login reg.timinglee.org -u admin
Password:
WARNING! Your credentials are stored unencrypted in '/root/.docker/config.json'.
Configure a credential helper to remove this warning. See
https://docs.docker.com/go/credential-store/
Login Succeeded
[root@master ~]# docker images --format "{{.Repository}}:{{.Tag}}" | awk -F "/" '/google/{system("docker tag "$0" reg.timinglee.org/k8s/"$3)}'
[root@master ~]# docker images --format "{{.Repository}}:{{.Tag}}" | awk -F "/" '/timinglee/{system("docker push "$0)}'
首先要创建k8s

[root@master ~]# kubeadm init --pod-network-cidr=10.244.0.0/16 \
--image-repository reg.timinglee.org/k8s \
--kubernetes-version v1.35.8 \
--cri-socket=unix:///var/run/cri-dockerd.sock
.
.
.
kubeadm join 172.25.254.100:6443 --token wm1hvf.mykag6j3900dbilb \
--discovery-token-ca-cert-hash sha256:6454295c25081331e13eebefcd0cab26b03ebdf0a121e554b397faf799238dd2
#如果初始化出问题
[root@master ~]# kubeadm reset --cri-socket=unix:///var/run/cri-dockerd.sock #可以重置集群设定
添加kubernets环境变量到本机
[root@master ~]# echo "export KUBECONFIG=/etc/kubernetes/admin.conf" > ~/.bash_profile
[root@master ~]# source ~/.bash_profile
[root@master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master NotReady control-plane 4m36s v1.35.7
添加node节点到本集群
[root@node1 ~]# kubeadm join 172.25.254.100:6443 --token wm1hvf.mykag6j3900dbilb \
--discovery-token-ca-cert-hash sha256:6454295c25081331e13eebefcd0cab26b03ebdf0a121e554b397faf799238dd2 --cri-socket=unix:///var/run/cri-dockerd.sock
[preflight] Running pre-flight checks
[WARNING SystemVerification]: kernel release 5.14.0-687.5.3.el9_8.x86_64 is unsupported. Supported LTS versions from the 5.x series are 5.4, 5.10 and 5.15. Any 6.x version is also supported. For cgroups v2 support, the recommended version is 5.10 or newer
[preflight] Reading configuration from the "kubeadm-config" ConfigMap in namespace "kube-system"...
[preflight] Use 'kubeadm init phase upload-config kubeadm --config your-config-file' to re-upload it.
W0822 16:39:45.426279 28063 utils.go:69] The recommended value for "bindAddress" in "KubeProxyConfiguration" is: ::; the provided value is: 0.0.0.0
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/instance-config.yaml"
[patches] Applied patch of type "application/strategic-merge-patch+json" to target "kubeletconfiguration"
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-check] Waiting for a healthy kubelet at http://127.0.0.1:10248/healthz. This can take up to 4m0s
[kubelet-check] The kubelet is healthy after 518.270485ms
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
# 测试
[root@master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master NotReady control-plane 6m5s v1.35.7
node1 NotReady <none> 8s v1.35.7
node2 NotReady <none> 16s v1.35.7
#如果做错可执行下面操作,然后重复上述操作
[root@node1 ~]# kubeadm reset --cri-socket unix:///var/run/cri-dockerd.sock
安装网络插件
[root@master ~]# ls
公共 视频 文档 音乐 anaconda-ks.cfg
模板 图片 下载 桌面 kube-flannel-v0.28.9.tar.gz
[root@master ~]# tar zxf kube-flannel-v0.28.9.tar.gz
[root@master ~]# cd flannel/
[root@master flannel]# docker load -i kube-flannel-v0.28.9.tar
Loaded image: ghcr.io/flannel-io/flannel-cni-plugin:v1.9.1-flannel3
Loaded image: ghcr.io/flannel-io/flannel:v0.28.9

[root@master ~]# docker tag ghcr.io/flannel-io/flannel-cni-plugin:v1.9.1-flannel3 reg.timinglee.org/flannel-io/flannel-cni-plugin:v1.9.1-flannel3
[root@master ~]# docker push reg.timinglee.org/flannel-io/flannel-cni-plugin:v1.9.1-flannel3
The push refers to repository [reg.timinglee.org/flannel-io/flannel-cni-plugin]
55afa1ecc21d: Pushed
e25563266d98: Pushed
v1.9.1-flannel3: digest: sha256:b60bc0d7ea43bc261720e4e12870f23e9b73127138e7aa8769aabab980e85153 size: 673
i Info → Not all multiplatform-content is present and only the available single-platform image was pushed
sha256:9fccdf677e6e26e76a4aa60da2113bab9852e8317287ba51b2c29778d2351345 -> sha256:b60bc0d7ea43bc261720e4e12870f23e9b73127138e7aa8769aabab980e85153
[root@master ~]# docker tag ghcr.io/flannel-io/flannel:v0.28.9 reg.timinglee.org/flannel-io/flannel:v0.28.9
[root@master ~]# docker push reg.timinglee.org/flannel-io/flannel:v0.28.9
The push refers to repository [reg.timinglee.org/flannel-io/flannel]
f923fe4d6cdf: Pushed
464e53b89363: Pushed
55afa1ecc21d: Mounted from flannel-io/flannel-cni-plugin
552426a46922: Pushed
779e1d234370: Pushed
74f5049831bd: Pushed
fef9ba352c99: Pushed
7e7d4790580f: Pushed
4f4fb700ef54: Pushed
dde022ac8ed4: Pushed
v0.28.9: digest: sha256:d666a036197fe6c8928f82b670d89f38f5830d25e70bfcc35641da06f03cfcad size: 2197
i Info → Not all multiplatform-content is present and only the available single-platform image was pushed
sha256:708a2c9c1cfbfe529d1dbb249cb7113af117f3ed26b5e3e4c8ee015e10555204 -> sha256:d666a036197fe6c8928f82b670d89f38f5830d25e70bfcc35641da06f03cfcad
[root@master ~]# cd flannel/
[root@master flannel]# vim kube-flannel.yml
[root@master flannel]# grep -n image: kube-flannel.yml
148: image: flannel-io/flannel:v0.28.9
175: image: flannel-io/flannel-cni-plugin:v1.9.1-flannel3
186: image: flannel-io/flannel:v0.28.9
[root@master flannel]# kubectl apply -f kube-flannel.yml
namespace/kube-flannel created
serviceaccount/flannel created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds created
[root@master flannel]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master Ready control-plane 133m v1.35.7
node1 Ready <none> 127m v1.35.7
node2 Ready <none> 127m v1.35.7
到此k8s部署完成