+harbor本地仓库的集群部署及ansibel批量工具的利用)
本文主要介绍如何部署一个 Kubernetesk8s集群包含一个本地 Harbor 私有镜像仓库采用一主两从的集群架构并使用 Ansible 工具进行批量自动化部署。一.harbor仓库规划部署主机名IP规划角色harbor172.25.254.250harbor仓库1.部署dockers本地仓库创建dockers的本地下载仓库[rootharbor ~]# vim /etc/yum.repos.d/docker.repo[docker]name dockerbaseurl http://172.25.254.250:4444/dockergpgcheck 0~下载安装两个软件包httpd和createrepo[rootharbor ~]# dnf install httpd createrepo -y[rootharbor ~]# mkdir /var/www/html/docker/ -p更改httpd服务端口为实验所需端口[rootharbor ~]# vim /etc/httpd/conf/httpd.conf# available when the service starts. See the httpd.service(8) man# page for more information.#Listen 12.34.56.78:80Listen 4444[rootharbor ~]# systemctl enable --now httpd把阿里云 docker‑ce 的 rpm 包下载到本地通过 httpd 搭建内网 yum 仓库[rootharbor ~]# dnf install docker-ce -downloadonly --destdir /mnt/ -y[rootharbor ~]# mv /mnt/*.rpm /var/www/html/docker/生成yum/dnf仓库元数据repodata目录[rootharbor ~]# createrepo -v /var/www/html/docker/[rootharbor ~]#vim /etc/yum.repos.d/docker.repo[docker]name dockerbaseurl http://172.25.254.250:4444/dockergpgcheck 0~使用搭建本地仓库下载dockers[rootharbor ~]# dnf install docker-ce -y2安装docker在harbor仓库节点配置开机自动加载 br_netfilter 内核模块[rootharbor ~]# echo br_netfilter /etc/modules-load.d/docker_mod.conf[rootharbor ~]# modprobe -a br_netfilter配置sysctl内核参数文件 /etc/sysctl.d/docker.conf[rootharbor ~]# vim /etc/sysctl.d/docker.confnet.bridge.bridge-nf-call-iptables 1#网桥流量交给 iptables 处理K8s Service iptables 模式依赖此项等于 0 网络会异常service 访问不通。net.bridge.bridge-nf-call-ip6tables 1#ipv6 网桥交给 iptables。net.ipv4.ip_forward 1#开启主机 IP 转发容器之间、Pod 跨节点通信必须开启[rootharbor ~]# systemctl restart systemd-modules-load.service[rootharbor ~]# sysctl --system修改docker service单元文件dockerd启动参数[rootharbor ~]# vim /lib/systemd/system/docker.serviceExecStart/usr/bin/dockerd -H fd:// --containerd/run/containerd/containerd.sock --iptablestrue##dockerd 允许 docker 操作主机 iptables 规则[rootharbor ~]# systemctl daemon-reload[rootharbor ~]# systemctl enable --now docker3.创建Harbor 私有仓库自签 TLS 证书[rootharbor ~]# mkdir /data/certs -p[rootharbor ~]# 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生成一套 Harbor 私有仓库使用的自签名 TLS HTTPS 证书包含私钥 公钥证书域名是reg.timinglee.org有效期 365 天。You are about to be asked to enter information that will be incorporatedinto your certificate request.4.编辑harbor配置文件[rootharbor ~]# tar zxf harbor-offline-installer-v2.5.4.tgz -C /opt/[rootharbor ~]# cd /opt/harbor/[rootharbor harbor]# lscommon cri-dockerd-0.4.4.amd64.tgz harbor.v2.5.4.tar.gz harbor.yml.tmpl LICENSEcommon.sh docker-compose.yml harbor.yml install.sh prepare[rootharbor harbor]#[rootharbor harbor]# cp harbor.yml.tmpl harbor.yml编辑配置文件[rootharbor harbor]# vim harbor.yml16 # The path of cert and key files for nginx17 certificate: /data/certs/timinglee.org.crt18 private_key: /data/certs/timinglee.org.key19 # # Uncomment following will enable tls communication between all harbor components32 # Remember Change the admin password from UI after launching Harbor.33 harbor_admin_password: lee执行 harbor 官方安装脚本部署 Harbor 私有镜像仓库同时启用 chartmuseum[rootharbor harbor]# ./install.sh --with-chartmuseum编写harbor启动脚本[rootharbor ~]# vim /lib/systemd/system/harbor.service[Unit]Descriptionharbor with Docker ComposeDocumentationhttps://reg.timinglee.com/compose/Afterdocker.service network-online.targetRequiresdocker.service[Service]TypeoneshotWorkingDirectory/opt/harborExecStart/usr/bin/docker compose up -dExecStop/usr/bin/docker compose downRemainAfterExityes[Install]WantedBymulti-user.target[rootharbor harbor]# docker compose downWARN[0000] /opt/harbor/docker-compose.yml: the attribute version is obsolete, it will be ignored, please remove it to avoid potential confusion[] down 4/6⠇ Container registryctl Stopping 1.9s✔ Container nginx Removed启动harbor[rootharbor ~]# systemctl enable --now harbor[rootharbor harbor]# docker compose psWARN[0000] /opt/harbor/docker-compose.yml: the attribute version is obsolete, it will be ignored, please remove it to avoid potential confusionNAME IMAGE COMMAND SERVICE CREATED STATUS PORTSharbor-core goharbor/harbor-core:v2.5.4 /harbor/entrypoint.… core 3 days ago Up 7 hours (healthy)harbor-db goharbor/harbor-db:v2.5.4 /docker-entrypoint.… postgresql 3 days ago Up 7 hours (healthy)harbor-jobservice goharbor/harbor-jobservice:v2.5.4 /harbor/entrypoint.… jobservice 3 days ago Up 7 hours (healthy)harbor-log goharbor/harbor-log:v2.5.4 /bin/sh -c /usr/loc… log 3 days ago Up 7 hours (healthy) 127.0.0.1:1514-10514/tcpharbor-portal goharbor/harbor-portal:v2.5.4 nginx -g daemon of… portal 3 days ago Up 7 hours (healthy)nginx goharbor/nginx-photon:v2.5.4 nginx -g daemon of… proxy 3 days ago Up 7 hours (healthy) 0.0.0.0:80-8080/tcp, [::]:80-8080/tcp, 0.0.0.0:443-8443/tcp, [::]:443-8443/tcpredis goharbor/redis-photon:v2.5.4 redis-server /etc/r… redis 3 days ago Up 7 hours (healthy)registry goharbor/registry-photon:v2.5.4 /home/harbor/entryp… registry 3 days ago Up 7 hours (healthy)registryctl goharbor/harbor-registryctl:v2.5.4 /home/harbor/start.… registryctl 3 days ago Up 7 hours (healthy)5.启动harbor并验证是否成功[rootharbor harbor]# mkdir /etc/docker/certs.d/reg.timinglee.org/ -p把 harbor 服务端生成的公钥证书 crt复制到 docker 证书目录命名为ca.crt[rootharbor harbor]# cp /data/certs/timinglee.org.crt /etc/docker/certs.d/reg.timinglee.org/ca.crt添加harbor主机域名映射[rootharbor harbor]# vim /etc/hosts127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4::1 localhost localhost.localdomain localhost6 localhost6.localdomain6172.25.254.250 harbor reg.timinglee.org[rootharbor harbor]# systemctl restart docker[rootharbor harbor]# docker compose up -d[rootharbor harbor]# docker compose up -dWARN[0000] /opt/harbor/docker-compose.yml: the attribute version is obsolete, it will be ignored, please remove it to avoid potential confusion[] up 9/9✔ Container harbor-jobservice Running 0.0s✔ Container redis Running 0.0s✔ Container registry Running 0.0s✔ Container harbor-log Running 0.0s✔ Container registryctl Running 0.0s✔ Container harbor-portal Running 0.0s✔ Container nginx Running 0.0s✔ Container harbor-core Running 0.0s✔ Container harbor-db Running 0.0s[rootharbor harbor]#[rootharbor harbor]# docker login reg.timinglee.org -u adminPassword:Login Succeeded这样就成功搭建好了harbor仓库二.构建部署kubernetes所需主机k8s集群服务器规划主机名IP规划角色harbor172.25.254.250harbor仓库k8s-master172.25.254.100k8s集群master控制节点k8s-node1172.25.254.10k8s集群worker1工作节点k8s-node2172.25.254.20k8s集群worker2工作节点1.所有k8s主机基础配置Kubernetes 硬性要求必须关闭 swap 交换分区否则 kubelet 无法正常启动会报错systemctl disable --now swap.targetsystemctl mask swap.targetsed /swap/s/^/#/g -i /etc/fstab给每台k8s主机安装docker[rootk8s-master~]# dnf install docker-ce -y[rootk8s-node1~]# dnf install docker-ce -y[rootk8s-node2~]# dnf install docker-ce -y给每个主机配置之前搭建的harbor仓库每个主机创建mkdir /etc/docker/certs.d/reg.timinglee.org/ -p在harbor主机中分发证书到所有主机[rootharbor ~]# for i in 100 10 20 do scp /data/certs/timinglee.org.crt root172.25.254.$i:/etc/docker/certs.d/reg.timinglee.org/ca.crt done重启dockersystemctl enable dockersystemctl restart docker给所有主机配置docker加速器--三台主机全部做[rootk8s-master ~]# vim /etc/docker/daemon.json{registry-mirrors:[https://reg.timinglee.org]}[rootk8s-master ~]# docker infoInsecure Registries:::1/128127.0.0.0/8Registry Mirrors:https://reg.timinglee.org/Live Restore Enabled: falseFirewall Backend: iptablesEnableUserlandProxy: trueUserlandProxyPath: /usr/bin/docker-proxy所有主机建立彼此解析--所有主机相互建立[rootk8s-node1 ~]# vim /etc/hosts127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4::1 localhost localhost.localdomain localhost6 localhost6.localdomain6172.25.254.100 k8s-master172.25.254.10 k8s-node1172.25.254.20 k8s-node2172.25.254.250 harbor reg.timinglee.org~所有主机配置kubernetes安装源[rootk8s-master ~]# vim /etc/yum.repos.d/kubernetes.repo[rootk8s-master ~]#[kubernetes]name kubernetesbaseurl https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.35/rpm/gpgcheck 0三.kubernetes的部署1.二进制包方式部署cri-dockerd--所有主机安装下载二进制安装包[rootdocker-node1 ~]# wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.4.4/cri-dockerd-0.4.4.amd64.tgz解压二进制压缩包[rootdocker-node1 ~]# tar zxf cri-dockerd-0.4.4.amd64.tgz[rootdocker-node1 ~]# cd cri-dockerd/[rootdocker-node1 cri-dockerd]# lscri-dockerd cri-docker.service cri-docker.socket安装cri-docker命令到系统[rootdocker-node1 cri-dockerd]# install -o root -g root -m 0755 cri-dockerd /usr/local/bin/cri-dockerd生成启动文件[rootdocker-node1 cri-dockerd]# cp cri-docker.s* /lib/systemd/systemcp: overwrite /lib/systemd/system/cri-docker.service? y[rootdocker-node1 cri-dockerd]# chmod x /lib/systemd/system/cri-docker.s*[rootdocker-node1 cri-dockerd]# vim /lib/systemd/system/cri-docker.service[Service]TypenotifyExecStart/usr/local/bin/cri-dockerd --network-plugincni --pod-infra-container-imagereg.timinglee.org/k8s/pause:3.10.1 --container-runtime-endpoint fd://ExecReload/bin/kill -s HUP $MAINPIDTimeoutSec0RestartSec2Restartalways[rootdocker-node1 cri-dockerd]# systemctl daemon-reload启动k8s服务[rootdocker-node1 cri-dockerd]# systemctl enable --now cri-docker.serviceCreated symlink /etc/systemd/system/multi-user.target.wants/cri-docker.service → /usr/lib/systemd/system/cri-docker.service.[rootdocker-node1 cri-dockerd]# systemctl status cri-docker.service● cri-docker.service - CRI Interface for Docker Application Container EngineLoaded: loaded (/usr/lib/system2.安装构建kubernetes 集群所需软件masterdnf install kubelet kubeadm kubectl -ysystemctl enable --now kubelet.servicenode节点dnf install kubelet kubeadm -ysystemctl enable --now kubelet.servicemaster节点中 kubectl 和kubeadm 补齐[rootmaster ~]# echo source (kubectl completion bash) ~/.bashrc[rootmaster ~]# echo source (kubeadm completion bash) ~/.bashrc[rootmaster ~]# source ~/.bashrc3.下载kubernetes集群所需镜像[rootk8s-master ~]# kubeadm config images listI0820 09:44:45.514598 81700 version.go:260] remote version is much newer: v1.36.3; falling back to: stable-1.35registry.k8s.io/kube-apiserver:v1.35.7registry.k8s.io/kube-controller-manager:v1.35.7registry.k8s.io/kube-scheduler:v1.35.7registry.k8s.io/kube-proxy:v1.35.7registry.k8s.io/coredns/coredns:v1.13.1registry.k8s.io/pause:3.10.1registry.k8s.io/etcd:3.6.6-0下载镜像[rootmaster ~]# kubeadm config images pull \--image-repository registry.aliyuncs.com/google_containers \--kubernetes-version v1.35.7 \--cri-socketunix:///var/run/cri-dockerd.sock[config/images] Pulled registry.aliyuncs.com/google_containers/kube-apiserver:v1.35.3[config/images] Pulled registry.aliyuncs.com/google_containers/kube-controller-manager:v1.35.34.上传镜像到本地harbor[rootmaster ~]# docker login reg.timinglee.org -u adminPassword:WARNING! Your credentials are stored unencrypted in /root/.docker/config.json.Configure a credential helper to remove this warning. Seehttps://docs.docker.com/go/credential-store/Login Succeeded[rootmaster ~]# docker images --format {{.Repository}}:{{.Tag}} | awk -F / /google/{system(docker tag $0 reg.timinglee.org/k8s/$3)}[rootmaster ~]# docker images --format {{.Repository}}:{{.Tag}} | awk -F / /timinglee/{system(docker push $0)}四.在master中初始化kubernetes集群1.在master中完成集群初始化[rootmaster ~]# kubeadm init --pod-network-cidr10.244.0.0/16 \--image-repository reg.timinglee.org/k8s \--kubernetes-version v1.35.7 \--cri-socketunix:///var/run/cri-dockerd.sock[rootk8s-master ~]# kubeadm token create --print-join-commandkubeadm join 172.25.254.100:6443 --token h115sx.xw4u6it67qou4mnr --discovery-token-ca-cert-hash sha256:03bb100d74df76f93186da52f2c6bd981592fa7a7b18fae97355c713322e4aa2[rootk8s-master ~]#在每个node节点添加凭证加入master集群[rootk8s-node1 ~]# kubeadm join 172.25.254.100:6443 --token h115sx.xw4u6it67qou4mnr --discovery-token-ca-cert-hash sha256:03bb100d74df76f93186da52f2c6bd981592fa7a7b18fae97355c713322e4aa2 --cri-socketunix:///var/run/cri-dockerd.sock[rootk8s-node2 ~]# kubeadm join 172.25.254.100:6443 --token h115sx.xw4u6it67qou4mnr --discovery-token-ca-cert-hash sha256:03bb100d74df76f93186da52f2c6bd981592fa7a7b18fae97355c713322e4aa2 --cri-socketunix:///var/run/cri-dockerd.sock如果初始化出问题[rootmaster ~]# kubeadm reset --cri-socketunix:///var/run/cri-dockerd.sock #可以重置集群设定[rootmaster ~]# kubectl get nodesNAME STATUS ROLES AGE VERSIONk8s-master Ready control-plane 3d7h v1.35.7k8s-node1 Ready none 3d7h v1.35.7k8s-node2 Ready none 3d7h v1.35.7[rootk8s-master ~]#2.添加kubernets环境变量到本机[rootmaster ~]# echo export KUBECONFIG/etc/kubernetes/admin.conf ~/.bash_profile[rootmaster ~]# source ~/.bash_profile[rootmaster ~]# kubectl get nodesNAME STATUS ROLES AGE VERSIONmaster NotReady control-plane 102s v1.35.3五.安装网络插件[rootk8s-master ~]# tar zxf kube-flannel-v0.28.9.tar.gz[rootk8s-master ~]# lsflannel kube-flannel-v0.28.9.tar.gz[rootk8s-master ~]# cd flannel/[rootk8s-master flannel]# docker load -i kube-flannel-v0.28.9.tarLoaded image: ghcr.io/flannel-io/flannel-cni-plugin:v1.9.1-flannel3Loaded image: ghcr.io/flannel-io/flannel:v0.28.9将安装包上传到harbor仓库[rootmaster ~]# docker tag ghcr.io/flannel-io/flannel-cni-plugin:v1.9.0-flannel1 reg.timinglee.org/flannel-io/flannel-cni-plugin:v1.9.0-flannel1[rootmaster ~]# docker push reg.timinglee.org/flannel-io/flannel-cni-plugin:v1.9.0-flannel1[rootmaster ~]# docker tag ghcr.io/flannel-io/flannel:v0.28.1 reg.timinglee.org/flannel-io/flannel:v0.28.1[rootmaster ~]# docker push reg.timinglee.org/flannel-io/flannel:v0.28.1[rootmaster ~]# vim kube-flannel.ymlimage: flannel-io/flannel:v0.28.1image: flannel-io/flannel-cni-plugin:v1.9.0-flannel1image: flannel-io/flannel:v0.28.1[rootmaster ~]# kubectl apply -f kube-flannel.ymlnamespace/kube-flannel createdserviceaccount/flannel createdclusterrole.rbac.authorization.k8s.io/flannel createdclusterrolebinding.rbac.authorization.k8s.io/flannel created[rootmaster ~]#kubectl get nodesNAME STATUS ROLES AGE VERSIONmaster Ready control-plane 13m v1.35.3node1 Ready none 9m44s v1.35.3node2 Ready none 9m36s v1.35.3六.利用ansible部署kubernetes运行环境1.安装ansible[rootharbor ~]# dnf install ansible-core.x86_64 ansible.noarch -y2.配置所需用户[rootharbor ~]# useradd devops[rootharbor ~]# echo lee | passwd --stdin devops更改用户 devops 的密码 。passwd所有的身份验证令牌已经成功更新[rootharbor ~]# su - devops[devopsharbor ~]$ mkdir ansible[devopsharbor ~]$ cd ansible/[devopsharbor ansible]$3.生成ansible的临时配置文件并建立运行环境[devopsharbor ansible]$ vim inventory[servers]172.25.254.100172.25.254.20172.25.254.10[devopsharbor ansible]$ vim ansible.cfg[defaults]inventory /home/devops/ansible/inventoryremote_user rootask_pass falsehost_key_checking false[devopsharbor ansible]$ ansible all -m ping172.25.254.20 | 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}172.25.254.100 | SUCCESS {ansible_facts: {discovered_interpreter_python: /usr/bin/python3},changed: false,ping: pong}[devopsharbor ansible]$建立用户[devopsharbor ansible]$ ansible all -m user -a namedevops statepresent[devopsharbor ansible]$ ansible all -m shell -a echo lee | passwd --stdin devops[devopsharbor ansible]$ ansible all -m lineinfile -a path/etc/sudoers linedevops ALL(ALL) NOPASSWD: ALL insertafterEOF4.生成ansible的主配置文件并测试[devopsharbor ansible]$ vim ansible.cfg[defaults]inventory /home/devops/ansible/inventoryremote_user devopsask_pass falsehost_key_checking false[privilege_escalation]become truebecome_method sudobecome_user rootbecome_ask_pass false[devopsharbor ansible]$ ansible all -m shell -a whoami 172.25.254.10 | CHANGED | rc0 root172.25.254.100 | CHANGED | rc0 root172.25.254.20 | CHANGED | rc0 root5.利用ansible剧本部署docker安装cri-dockerd以及部署k8s软件[devopsharbor ansible]$ tar zxf cri-dockerd-0.4.4.amd64.tgz[devopsharbor ansible]$ lsansible.cfg cri-dockerd cri-dockerd-0.4.4.amd64.tgz inventory kubernetes-devops.yml[devopsharbor ansible]$ cd cri-dockerd/[devopsharbor cri-dockerd]$ lscri-dockerd cri-docker.service cri-docker.socket[devopsharbor cri-dockerd]$ vim cri-docker.service[Service]TypenotifyExecStart/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --network-plugincni --pod-infra-container-imagereg.timinglee.org/k8s/pause:3.10.1ExecReload/bin/kill -s HUP $MAINPIDTimeoutSec0RestartSec2Restartalwaysansibel剧本搭建[devopsharbor ansible]$ vim kubernetes-devops.yml- name: devops k8s from ansiblehosts: allbecome: truetasks:- name: setup docker repoyum_repository:name: dockerdescription: dockerbaseurl: http://172.25.254.254:4444/dockerfile: dockergpgcheck: no- name: install dockerdnf:name: docker-cestate: present- name: setup docker.service modify ExecStartreplace:path: /lib/systemd/system/docker.serviceregexp: ExecStart/usr/bin/dockerd -H fd:// --containerd/run/containerd/containerd.sockreplace: ExecStart/usr/bin/dockerd -H fd:// --containerd/run/containerd/containerd.sock --iptablestrue- name: daemon‑reload after modify docker.servicesystemd:daemon_reload: yes- name: setup docker registry daemon.jsoncopy:content: |{registry-mirrors:[https://reg.timinglee.org]}dest: /etc/docker/daemon.json- name: setup docker certs directoryfile:path: /etc/docker/certs.d/reg.timinglee.orgstate: directorymode: 0755- name: copy harbor ca.crt to target nodescopy:src: /data/certs/timinglee.org.crtdest: {{ item.dest }}loop:- dest: /etc/docker/certs.d/reg.timinglee.org/ca.crt- dest: /etc/pki/ca-trust/source/anchors/ca.crt- name: write br_netfilter module configcopy:dest: {{ item.dest }}content: {{ item.value }}loop:- dest: /etc/modules-load.d/docker_mod.confvalue: br_netfilter- dest: /etc/sysctl.d/docker.confvalue: |net.bridge.bridge-nf-call-iptables 1net.bridge.bridge-nf-call-ip6tables 1net.ipv4.ip_forward 1- name: update ca trust and reload sysctlshell: |update-ca-trust extractsysctl --systemargs:executable: /bin/bash- name: start and enable servicesservice:name: {{ item }}state: restartedenabled: yesloop:- docker- systemd-modules-load.service- name: setup cri-dockerd binary and unit filescopy:src: {{ item.src }}dest: {{ item.dest }}mode: {{ item.mode }}loop:- src: ./cri-dockerd/cri-dockerddest: /usr/bin/cri-dockerdmode: 0755- src: ./cri-dockerd/cri-docker.servicedest: /lib/systemd/system/cri-docker.servicemode: 0644- src: ./cri-dockerd/cri-docker.socketdest: /lib/systemd/system/cri-docker.socketmode: 0644- name: systemd daemon-reload after push cri‑docker unit filessystemd:daemon_reload: yes- name: update ca trust and apply sysctl configshell: |update-ca-trust extractsysctl --systemargs:executable: /bin/bash- name: start and enable servicesservice:name: {{ item }}state: restartedenabled: yesloop:- docker- systemd-modules-load.service- cri-docker- name: install kubernetes from ansiblehosts: alltasks:- name: setup k8s repoyum_repository:name: kubernetesdescription: kubernetesbaseurl: https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.35/rpmfile: kubernetesgpgcheck: no- name: install software in masterdnf:name: {{item}}state: presentloop:- kubeadm-1.35.7-150500.1.1- kubelet-1.35.7-150500.1.1- kubectl-1.35.7-150500.1.1when: inventory_hostname 172.25.254.100- name: install software in work nodednf:name: {{item}}state: presentloop:- kubeadm-1.35.7-150500.1.1- kubelet-1.35.7-150500.1.1when: inventory_hostname 172.25.254.10 or inventory_hostname 172.25.254.20- name: setup kubectl kubeadm complicationlineinfile:path: /root/.bashrcline: |source (kubectl completion bash)source (kubeadm completion bash)when: inventory_hostname 172.25.254.100- name: start kubeletservice:name: kubeletstate: startedenabled: yes可以利用ansible一键批量部署k8s使用ansible剧本[devopsharbor ansible]$ ansible-playbook kubernetes-devops.yml部署完成后#让补齐功能生效[rootk8s-master mnt]# source ~/.bashrc[rootk8s-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)[rootk8s-master mnt]# kubeadmcerts config init kubeconfig token versioncompletion help join reset upgrade[rootk8s-master mnt]# systemctl status kubelet.service● kubelet.service - kubelet: The Kubernetes Node AgentLoaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; preset: disabled)Drop-In: /usr/lib/systemd/system/kubelet.service.d└─10-kubeadm.confActive: activating (auto-restart) (Result: exit-code) since Tue 2026-08-18 17:09:25 CST; 1s agoDocs: https://kubernetes.io/docs/Process: 79433 ExecStart/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_Main PID: 79433 (codeexited, status1/FAILURE)