K8S的安装以及运行

一.前期准备

Linux版本 CPU MEM
Centos7.8 amd架构 双核 4G/node
master node1 node2
192.168.8.10 192.168.8.20 192.168.8.30

更换主机名

hostnamectl set-hostname master
hostnamectl set-hostname node01
hostnamectl set-hostname node02

添加对应域名解析

cat >> /etc/hosts << EOF
192.168.8.10 master
192.168.8.20 node01
192.168.8.30 node02
EOF

防火墙,SElinux

systemctl stop firewalld
systemctl disable firewalld
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

时间同步

timedatectl set-timezone Asia/Shanghai;timedatectl set-local-rtc 0

禁用swap

swapoff -a && sed -i '/swap/s/^/#/' /etc/fstab       
#查看禁用效果
free -h 

配置集群无密登录 master到node01,node02无密码

ssh-keygen -t rsa

ssh-copy-id root@node01

ssh-copy-id root@node02

优化内核参数(在主节点粘贴)

modprobe br_netfilter

cat > /etc/sysctl.d/kubernetes.conf << EOF
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
net.ipv4.tcp_tw_recycle = 0
vm.swappiness = 0
vm.overcommit_memory = 1
vm.panic_on_oom = 0
fs.inotify.max_user_instances = 8192
fs.inotify.max_user_watches = 1048576
fs.file-max = 52706963
fs.nr_open = 52706963
net.ipv6.conf.all.disable_ipv6 = 1
net.netfilter.nf_conntrack_max = 2310720
EOF

sysctl -p /etc/sysctl.d/kubernetes.conf

在主节点粘贴

scp /etc/sysctl.d/kubernetes.conf node01:/etc/sysctl.d/
scp /etc/sysctl.d/kubernetes.conf node02:/etc/sysctl.d/

在从节点查看(node)

sysctl -p /etc/sysctl.d/kubernetes.conf

到此基本环境准备完毕,需要在各节点上准备kubernetesyum源,先来master节点上操作,node也要写

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

部署k8s组件(master)

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

部署node组件(node)

yum install kubelet-1.18.0 kubeadm-1.18.0 -y --nogpgcheck
systemctl start kubelet
systemctl enable kubelet

更改docker默认Cgroup驱动

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
 "registry-mirrors": [
           "https://docker.m.daocloud.io",
           "https://luzxy6tp.mirror.aliyuncs.com",
           "https://hub.uuuadc.top",
           "https://docker.anyhub.us.kg",
           "https://dockerhub.jobcher.com",
           "https://dockerhub.icu",
           "https://docker.ckyl.me",
           "https://docker.awsl9527.cn"],
 "exec-opts": ["native.cgroupdriver=systemd"]
}

EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

kubeadm初始化

cd 到那个目录下在哪里生成,在哪里执行(我的是再root)

kubeadm config print init-defaults > kubeadm-config.yaml
sudo tee /root/kubeadm-config.yaml <<-'EOF'
apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 192.168.8.10
  bindPort: 6443
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  name: master
  taints:
  - effect: NoSchedule
    key: node-role.kubernetes.io/master
---
apiServer:
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns:
  type: CoreDNS
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.18.0
networking:
  dnsDomain: cluster.local
  serviceSubnet: 10.96.0.0/12
  podSubnet: 10.244.0.0/16
scheduler: {}
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
EOF

初始化集群

提前导入镜像,没有的可以找我要

master节点:
docker load -i etcd.tar 
docker load -i quay.io-flannel.tar
docker load -i kube-apiserver.tar 
docker load -i kube-controller-manager.tar 
docker load -i kube-proxy.tar 
docker load -i kube-scheduler.tar 
docker load -i kube-webhook.tar 
docker load -i coredns.tar
docker load -i pause.tar 
docker load -i flannel-plugin.tar


node节点:
docker load -i pause.tar
docker load -i kube-proxy.tar
docker load -i quay.io-flannel.tar
docker load -i flannel-plugin.tar

初始化k8s

kubeadm init --config=kubeadm-config.yaml

成功后提示:

把这三句,复制到node上去(这些都是复制你们上面出现的)

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

这个也是复制node上去

kubeadm join 192.168.8.10:6443 --token abcdef.0123456789abcdef \
    --discovery-token-ca-cert-hash sha256:a2ec410cea22ef589a7af6072008fbace244a9106bde030e771e9d933124ceec

启动k8s

systemctl enable kubelet 

K8S的基本用法

1. 创建 Deployment(2 种方式)

K8s 操作分命令式(直接输命令)声明式(用 YAML 文件),生产环境推荐声明式(可版本控制、重复执行)。

方式 操作命令 / 示例 说明
命令式(快速测试) bash# 创建Nginx Deployment,副本数2,镜像版本1.24kubectl create deployment nginx --image=nginx:1.24 --replicas=2 适合临时测试,无法保存配置。
声明式(生产推荐) 1. 创建 YAML 文件(nginx-deploy.yaml):yamlapiVersion: apps/v1kind: Deploymentmetadata: name: nginx-deploy labels: app: nginxspec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.24 ports: - containerPort: 80 resources: # 资源限制(避免占用过多节点资源) requests: cpu: "100m" # 最小需要100毫核(0.1核) memory: "128Mi" # 最小需要128MB内存 limits: cpu: "500m" memory: "256Mi"2. 执行创建:bashkubectl apply -f nginx-deploy.yaml YAML 文件可提交到 Git,实现 “配置即代码”,重复执行apply不会重复创建(仅更新差异)。
2. 查看 Deployment 状态
# 查看所有Deployment
kubectl get deployments
# 查看指定Deployment的详细信息(如事件、副本状态)
kubectl describe deployment nginx-deploy
# 查看Deployment管理的Pod(标签匹配app=nginx)
kubectl get pods -l app=nginx  # -l:按标签筛选
# 查看Pod的详细日志(排查故障用)
kubectl logs <pod-name>  # 替换为实际Pod名,如nginx-deploy-7f98d7c6b4-2xqzk
# 进入Pod内部(类似docker exec)
kubectl exec -it <pod-name> -- /bin/bash  # 进入后可执行ls、cat等命令
3. 操作 Deployment:扩缩容、更新、回滚
  • 扩缩容(调整副本数)

    # 命令式:将副本数从2调整为3
    kubectl scale deployment nginx-deploy --replicas=3
    # 声明式:修改YAML文件中replicas: 3,再执行apply
    kubectl apply -f nginx-deploy.yaml
    
  • 滚动更新(升级 Nginx 版本)

    # 命令式:将镜像从1.24升级到1.25
    kubectl set image deployment nginx-deploy nginx=nginx:1.25
    # 声明式:修改YAML中image: nginx:1.25,再执行apply
    kubectl apply -f nginx-deploy.yaml
    # 查看更新状态(是否完成)
    kubectl rollout status deployment nginx-deploy
    
  • 回滚(更新失败时)

    # 查看更新历史
    kubectl rollout history deployment nginx-deploy
    # 回滚到上一个版本
    kubectl rollout undo deployment nginx-deploy
    # 回滚到指定版本(需先看历史版本号)
    kubectl rollout undo deployment nginx-deploy --to-revision=1
    
4. 删除 Deployment
# 命令式删除
kubectl delete deployment nginx-deploy
# 声明式删除(删除YAML文件对应的资源)
kubectl delete -f nginx-deploy.yaml

3.2 第二步:用 Service 暴露 Pod 访问

Pod 的 IP 是 “动态的”(Pod 重启后 IP 会变),Service 为 Pod 提供固定访问地址,并实现负载均衡。

1. Service 的 3 种核心类型
类型 作用说明 适用场景
ClusterIP 仅集群内部可访问(默认类型),提供集群内固定 IP。 集群内服务间通信(如后端 API 给前端调用)。
NodePort 在每个 Node 上开放一个端口,外部可通过NodeIP:NodePort访问 Pod。 测试环境外部访问(如本地 Minikube 测试)。
LoadBalancer 结合云服务商负载均衡器(如 AWS ELB、阿里云 SLB),外部通过负载均衡器 IP 访问。 生产环境外部访问(公网服务)。
2. 创建 Service(以 NodePort 为例)
  • 命令式创建

    (关联之前的 nginx-deploy):

    # 暴露nginx-deploy的80端口,类型为NodePort
    kubectl expose deployment nginx-deploy --type=NodePort --port=80 --target-port=80
    # --port:Service的端口;--target-port:Pod的容器端口(需与Deployment中containerPort一致)
    
  • 声明式创建

    (nginx-svc.yaml):

    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-svc
    spec:
      type: NodePort
      selector:
        app: nginx  # 关联标签为app=nginx的Pod(与Deployment的selector一致)
      ports:
      - port: 80        # Service端口
        targetPort: 80  # Pod容器端口
        nodePort: 30080 # 可选:指定NodePort(范围30000-32767),不指定则自动分配
    

    执行创建:

    kubectl apply -f nginx-svc.yaml
    
3. 查看和访问 Service
# 查看所有Service
kubectl get svc
# 查看指定Service的详细信息(含NodePort、Endpoints(Pod IP列表))
kubectl describe svc nginx-svc
# 输出示例中会有:NodePort: <unset> 30080/TCP(30080即为NodePort)
  • Minikube 中访问 NodePort 服务

    Minikube 提供便捷命令获取访问地址:

    minikube service nginx-svc --url
    # 输出示例:http://192.168.49.2:30080,直接用浏览器访问即可看到Nginx首页
    
  • Linux/kind 中访问 NodePort 服务

    若集群在本地,直接用

    localhost:NodePort
    

    访问(如)

    http://localhost:30080
    
4. 删除 Service
kubectl delete svc nginx-svc
# 或声明式删除:kubectl delete -f nginx-svc.yaml

3.3 第三步:用 ConfigMap/Secret 管理配置

避免将配置硬编码到镜像中,通过 ConfigMap/Secret 动态注入 Pod。

1. ConfigMap:存储非敏感配置

以 “Nginx 自定义首页” 为例,用 ConfigMap 存储首页内容:

  • 创建 ConfigMap :

    # 从文件创建(先创建index.html文件)
    echo "<h1>Hello K8s ConfigMap!</h1>" > index.html
    kubectl create configmap nginx-config --from-file=index.html
    
  • 在 Deployment 中挂载 ConfigMap(修改 nginx-deploy.yaml):

    spec:
      containers:
      - name: nginx
        image: nginx:1.24
        ports:
        - containerPort: 80
        volumeMounts:  # 挂载ConfigMap到容器内目录
        - name: nginx-html
          mountPath: /usr/share/nginx/html/index.html  # 覆盖Nginx默认首页
          subPath: index.html  # 仅挂载index.html文件(避免覆盖整个目录)
      volumes:  # 定义卷(关联ConfigMap)
      - name: nginx-html
        configMap:
          name: nginx-config  # 关联之前创建的ConfigMap
    
  • 更新 Deployment 并验证

    kubectl apply -f nginx-deploy.yaml
    # 访问Nginx服务,会看到“Hello K8s ConfigMap!”
    
2. Secret:存储敏感配置

以 “存储数据库密码” 为例:

  • 创建 Secret(注意:Secret 内容需用 Base64 编码):

    # 1. 编码密码(如密码为123456)
    echo -n "123456" | base64  # 输出:MTIzNDU2
    # 2. 创建Secret(命令式)
    kubectl create secret generic db-secret --from-literal=db-password=MTIzNDU2
    # 或用YAML创建(db-secret.yaml):
    # apiVersion: v1
    # kind: Secret
    # metadata:
    #   name: db-secret
    # type: Opaque
    # data:
    #   db-password: MTIzNDU2  # Base64编码后的密码
    
  • 在 Pod 中使用 Secret

    (2 种方式):

    1. 作为环境变量:

      spec:
        containers:
        - name: app
          image: my-app:v1
          env:
          - name: DB_PASSWORD
            valueFrom:
              secretKeyRef:
                name: db-secret  # Secret名
                key: db-password  # Secret的Key
      
    2. 作为文件挂载:

      spec:
        containers:
        - name: app
          image: my-app:v1
          volumeMounts:
          - name: db-secret-volume
            mountPath: /etc/secrets  # 挂载到容器内目录
            readOnly: true  # 只读(安全)
        volumes:
        - name: db-secret-volume
          secret:
            secretName: db-secret
      

3.4 第四步:用 PV/PVC 实现持久化存储

Pod 删除后,容器内数据会丢失,需用 PV/PVC 将数据存储到外部(如 NFS、云硬盘)。

1. 流程:先创建 PV,再创建 PVC,最后 Pod 挂载 PVC
  • 1. 创建 PV(以 NFS 为例,需先搭建 NFS 服务器):创建nginx-pv.yaml

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: nginx-pv
    spec:
      capacity:
        storage: 1Gi  # PV容量
      accessModes:
        - ReadWriteMany  # 访问模式:多节点读写(其他模式:ReadWriteOnce单节点读写、ReadOnlyMany多节点只读)
      persistentVolumeReclaimPolicy: Retain  # 回收策略:Retain(保留数据)、Delete(删除PV时删除数据)
      nfs:
        path: /nfs/nginx  # NFS服务器的共享目录
        server: 192.168.1.100  # NFS服务器IP
    

    执行创建:kubectl apply -f nginx-pv.yaml

  • 2. 创建 PVC(申请 PV 资源):创建nginx-pvc.yaml

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: nginx-pvc
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 1Gi  # 申请1Gi存储(需与PV容量匹配)
    

    执行创建:kubectl apply -f nginx-pvc.yaml

  • 3. 在 Deployment 中挂载 PVC:修改nginx-deploy.yaml,添加存储挂载:

    spec:
      containers:
      - name: nginx
        image: nginx:1.24
        ports:
        - containerPort: 80
        volumeMounts:
        - name: nginx-storage
          mountPath: /usr/share/nginx/html  # 将PVC挂载到Nginx首页目录
      volumes:
      - name: nginx-storage
        persistentVolumeClaim:
          claimName: nginx-pvc  # 关联PVC
    

    执行更新:kubectl apply -f nginx-deploy.yaml

2. 查看 PV/PVC 状态
# 查看PV(STATUS为Bound表示已被PVC绑定)
kubectl get pv
# 查看PVC(STATUS为Bound表示已绑定PV)
kubectl get pvc

四、日常运维:常用 kubectl 命令

操作场景 命令示例
查看集群状态 kubectl get nodes(查看节点)、kubectl get namespaces(查看命名空间)
查看资源列表 kubectl get pods/deployments/svc/cm/secret/pv/pvc(缩写:pod/deploy/svc)
查看资源详情 kubectl describe <资源类型> <资源名>(如kubectl describe pod nginx-pod
查看 Pod 日志 kubectl logs <pod-name>(实时日志:-f参数,如kubectl logs -f nginx-pod
进入 Pod 容器 kubectl exec -it <pod-name> -- /bin/bash(若容器无 bash,用/bin/sh
复制文件到 Pod kubectl cp <本地文件路径> <pod-name>:<容器内路径>(如kubectl cp index.html nginx-pod:/usr/share/nginx/html/
强制删除 Pod kubectl delete pod <pod-name> --force --grace-period=0(用于 Pod 卡住时)
查看资源 YAML 配置 kubectl get <资源类型> <资源名> -o yaml(如kubectl get deploy nginx-deploy -o yaml

五、生产环境注意事项

  1. 不要用 Minikube/kind 部署生产环境

    :生产需用多节点集群,推荐工具:

    • 云厂商托管集群:AWS EKS、阿里云 ACK、Google GKE。
    • 自建集群:kubespray、k3s(轻量)、RKE(Rancher)。
  2. 优先用声明式(YAML)管理资源:将 YAML 文件提交到 Git,实现 “配置即代码”,避免手动命令操作。

  3. 设置资源限制(resources.limits/requests):防止单个 Pod 占用过多节点资源,导致其他服务不可用。

  4. Secret 安全:Base64 编码不是加密,生产需配合外部密钥管理(如 HashiCorp Vault、云厂商 KMS)。

  5. 备份 etcd:etcd 是集群 “数据库”,需定期备份(etcdctl snapshot save命令)。

  6. 监控和日志:部署 Prometheus(监控)+ Grafana(可视化)、ELK Stack(日志收集)。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐