一、Kubernetes简介
- 在Docker 作为高级容器引擎快速发展的同时,在Google内部,容器技术已经应用了很多年Borg系统运行管理着成干上万的容器应用。
- Kubernetes项目来源于Borg,可以说是集结了Borg设计思想的精华,并且吸收了Borg系统中的经验和教训。
- Kubernetes对计算资源进行了更高层次的抽象,通过将容器进行细致的组合,将最终的应用服务交给用户。
kubernetes的本质是一组服务器集群,它可以在集群的每个节点上运行特定的程序,来对节点中的容器进行管理。目的是实现资源管理的自动化,主要提供了如下的主要功能:
- 自我修复:一旦某一个容器崩溃,能够在1秒中左右迅速启动新的容器
- 弹性伸缩:可以根据需要,自动对集群中正在运行的容器数量进行调整
- 服务发现:服务可以通过自动发现的形式找到它所依赖的服务
- 负载均衡:如果一个服务起动了多个容器,能够自动实现请求的负载均衡
- 版本回退:如果发现新发布的程序版本有问题,可以立即回退到原来的版本
- 存储编排:可以根据容器自身的需求自动创建存储卷
二、Kubernetes部署
2.1 实验环境
master | 172.25.254.200 |
node1 | 172.25.254.10 |
node2 | 172.25.254.20 |
docker-node1 | 172.25.254.100(harbor仓库) |
2.2 环境部署
2.2.1 基础配置
# 添加解析 三台主机都需添加
[root@node2 ~]# vim /etc/hosts
[root@node2 ~]# cat /etc/hosts
172.25.254.200 k8s-master.txy.org
172.25.254.10 k8s-node1.txy.org
172.25.254.20 k8s-node2.txy.org
安装docker,确保登录成功
# 安装docker
[root@master ~]# ls
anaconda-ks.cfg docker.tar.gz Downloads Pictures Templates zuoyedir
Desktop Documents Music Public Videos
[root@master ~]# tar zxf docker.tar.gz
[root@master ~]# ls
anaconda-ks.cfg docker-ce-rootless-extras-27.1.2-1.el9.x86_64.rpm Pictures
containerd.io-1.7.20-3.1.el9.x86_64.rpm docker-compose-plugin-2.29.1-1.el9.x86_64.rpm Public
Desktop docker.tar.gz Templates
docker-buildx-plugin-0.16.2-1.el9.x86_64.rpm Documents Videos
docker-ce-27.1.2-1.el9.x86_64.rpm Downloads zuoyedir
docker-ce-cli-27.1.2-1.el9.x86_64.rpm Music
[root@master ~]# dnf install *.rpm -y
[root@docker ~]# cd certs/
[root@docker certs]# ls
txy.org.crt txy.org.key
[root@master ~]# mkdir /etc/docker/certs.d/reg.txy.org/ -p
# 传给三个主机
[root@docker-node1 certs]# scp /root/certs/txy.org.crt root@172.25.254.200:/etc/docker/certs.d/reg.txy.org/ca.crt
[root@master ~]# vim /etc/hosts # 添加reg.txy.org的解析
[root@master ~]# docker login reg.txy.org
Username: txy
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credential-stores
Login Succeeded
[root@master ~]# scp *.rpm root@172.25.254.10:/root
[root@master ~]# scp *.rpm root@172.25.254.20:/root
[root@node1 ~]# dnf install *.rpm -y
[root@node2 ~]# dnf install *.rpm -y
[root@master ~]# scp -r /etc/docker/ root@172.25.254.10:/etc/
[root@master ~]# scp -r /etc/docker/ root@172.25.254.20:/etc/
[root@node1 docker]# systemctl enable --now docker
[root@node2 docker]# systemctl enable --now docker
[root@node1 docker]# vim /etc/hosts # 添加解析 reg.txy.org - 172.25.254.100
[root@node2 docker]# vim /etc/hosts
# 若harbor仓库出现登录不上的情况,则
[root@docker-node1 harbor]# ./install.sh --with-chartmuseum
[root@docker-node1 harbor]# docker compose stop
[root@docker-node1 harbor]# docker compose up -d
[root@docker-node1 harbor]# vim /etc/docker/daemon.json
[root@docker-node1 harbor]# systemctl daemon-reload
[root@docker-node1 harbor]# systemctl restart docker
[root@docker-node1 harbor]# docker logout reg.txy.org
Removing login credentials for reg.txy.org
[root@docker-node1 harbor]# docker login reg.txy.org
Username: admin
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credential-stores
Login Succeeded
[root@docker-node1 harbor]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://reg.txy.org","http://hub-mirror.c.163.com"]
}
2.2.2 禁用swap和本地解析
[root@node1 docker]# systemctl mask dev-nvme0n1p3.swap
Unit dev-nvme0n1p3.swap does not exist, proceeding anyway.
Created symlink /etc/systemd/system/dev-nvme0n1p3.swap → /dev/null.
[root@node1 docker]# swapoff -a
[root@node2 docker]# systemctl mask dev-nvme0n1p3.swap
Unit dev-nvme0n1p3.swap does not exist, proceeding anyway.
Created symlink /etc/systemd/system/dev-nvme0n1p3.swap → /dev/null.
[root@node2 docker]# swapoff -a
[root@master ~]# systemctl mask dev-nvme0n1p3.swap
Unit dev-nvme0n1p3.swap does not exist, proceeding anyway.
Created symlink /etc/systemd/system/dev-nvme0n1p3.swap → /dev/null.
[root@master ~]# swapoff -a
[root@master ~]# vim /etc/fstab
2.2.3 安装K8s部署工具
[root@master ~]# mkdir /software
[root@master ~]# mv cri-dockerd-0.3.14-3.el8.x86_64.rpm libcgroup-0.41-19.el8.x86_64.rpm /software/
[root@master ~]# cd /software/
[root@master software]# ls
cri-dockerd-0.3.14-3.el8.x86_64.rpm libcgroup-0.41-19.el8.x86_64.rpm
[root@master software]# dnf install *.rpm -y
[root@master software]# systemctl start cri-docker
[root@master software]# scp cri-dockerd-0.3.14-3.el8.x86_64.rpm libcgroup-0.41-19.el8.x86_64.rpm root@172.25.254.10:/software/
[root@master software]# scp cri-dockerd-0.3.14-3.el8.x86_64.rpm libcgroup-0.41-19.el8.x86_64.rpm root@172.25.254.20:/software/
[root@node1 ~]# mkdir software/
[root@node1 ~]# dnf install /software/*.rpm -y
[root@node2 ~]# mkdir software/
[root@node2 ~]# dnf install /software/*.rpm -y
[root@master software]# systemctl enable --now cri-docker
[root@node1 ~]# systemctl enable --now cri-docker
[root@node2 ~]# systemctl enable --now cri-docker
[root@master yum.repos.d]# vim k8s.repo
[root@master yum.repos.d]# cat k8s.repo
[k8s]
name=k8s
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/rpm
gpgcheck=0
[root@master yum.repos.d]# dnf makecache
[root@master ~]# dnf install kubelet-1.30.0-150500.1.1 kubeadm-1.30.0-150500.1.1 --downloadonly --downloaddir=/software
或[root@master ~]# dnf install kubelet-1.30.0 kubeadm-1.30.0 kubectl-1.30.0 -y
[root@master ~]# dnf install bash-completion -y
[root@master ~]# echo "source <(kubectl completion bash)" >> ~/.bashrc
[root@master ~]# source ~/.bashrc
#拉取k8s集群所需要的镜像
[root@master ~]# kubeadm config images pull --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.30.0 --cri-socket=unix:///var/run/cri-dockerd.sock
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-apiserver:v1.30.0
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-controller-manager:v1.30.0
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-scheduler:v1.30.0
[config/images] Pulled registry.aliyuncs.com/google_containers/kube-proxy:v1.30.0
[config/images] Pulled registry.aliyuncs.com/google_containers/coredns:v1.11.1
[config/images] Pulled registry.aliyuncs.com/google_containers/pause:3.9
[config/images] Pulled registry.aliyuncs.com/google_containers/etcd:3.5.12-0
上传镜像到harbor仓库,要注意 pull 之前得确保先在harbor仓库中创建k8s这个项目
[root@master yum.repos.d]# docker images | awk '/google/{ print $1":"$2}' | awk -F "/" '{system("docker tag "$0" reg.txy.org/k8s/"$3)}'
[root@master ~]# docker login reg.txy.org -u admin
[root@master yum.repos.d]# docker images | awk '/k8s/{system("docker push "$1":"$2)}'
2.2.4 集群初始化
#启动kubelet服务
[root@master ~]# systemctl status kubelet.service
#指定网络插件名称及基础容器镜像
[root@master ~]# vim /lib/systemd/system/cri-docker.service
ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --network-plugin=cni --pod-infra-container-image=reg.txy.org/k8s/pause:3.9
[root@master ~]# systemctl daemon-reload
[root@master ~]# systemctl restart cri-docker
[root@master ~]# ll /var/run/cri-dockerd.sock
srw-rw---- 1 root docker 0 Sep 10 09:26 /var/run/cri-dockerd.sock
[root@master ~]# scp /lib/systemd/system/cri-docker.service root@172.25.254.10:/lib/systemd/system/cri-docker.service
[root@master ~]# scp /lib/systemd/system/cri-docker.service root@172.25.254.20:/lib/systemd/system/cri-docker.service
[root@node1 ~]# systemctl daemon-reload
[root@node2 ~]# systemctl daemon-reload
[root@node1 ~]# systemctl restart cri-docker
[root@node2 ~]# systemctl restart cri-docker
#执行初始化命令
[root@master ~]# kubeadm init --pod-network-cidr=172.25.0.0/16 --image-repository reg.txy.org/k8s --kubernetes-version v1.30.0 --cri-socket=unix:///var/run/cri-dockerd.sock
[root@master ~]# kubeadm config images list
I0910 11:54:29.962229 41325 version.go:256] remote version is much newer: v1.31.0; falling back to: stable-1.30
registry.k8s.io/kube-apiserver:v1.30.4
registry.k8s.io/kube-controller-manager:v1.30.4
registry.k8s.io/kube-scheduler:v1.30.4
registry.k8s.io/kube-proxy:v1.30.4
registry.k8s.io/coredns/coredns:v1.11.1
registry.k8s.io/pause:3.9
registry.k8s.io/etcd:3.5.12-0
# 若初始化失败,则重置
[root@master ~]# kubeadm reset --cri-socket=unix:///var/run/cri-dockerd.sock
2.2.5 安装flannel网络插件
#指定集群配置文件变量
[root@master ~]# export KUBECONFIG=/etc/kubernetes/admin.conf
#当前节点没有就绪,还没有安装网络插件,容器没有运行
[root@master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master.zx.org NotReady control-plane 5m41s v1.30.0
[root@master ~]# echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
[root@master ~]# source ~/.bash_profile
[root@master ~]# vim kube-flannel.yml # 将镜像下载地址改成本地(image)
[root@master ~]# grep -n image kube-flannel.yml #需要修改以下几行
146: image: flannel/flannel:v0.25.5
173: image: flannel/flannel-cni-plugin:v1.5.1-flannel1
184: image: flannel/flannel:v0.25.5
[root@master ~]# docker load -i flannel-0.25.5.tag.gz
# docker仓库中新建flannel项目
# 打标签上传
[root@master ~]# docker tag flannel/flannel:v0.25.5
[root@master ~]# docker push reg.txy.org/flannel/flannel:v0.25.5
[root@master ~]# docker tag flannel/flannel-cni-plugin:v1.5.1-flannel1
[root@master ~]# docker push reg.txy.org/flannel/flannel-cni-plugin:v1.5.1-flannel1
#安装flannel网络插件
[root@master ~]# 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 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master.txy.org Ready control-plane 25m v1.30.0
2.2.6 节点扩容
在所有的worker节点中确认部署好以下内容,并禁用swap;
安装以下内容:
kubelet-1.30.0
kubeadm-1.30.0
kubectl-1.30.0
docker-ce
cri-dockerd
修改cri-dockerd启动文件添加:
--network-plugin=cni
--pod-infra-container-image=reg.txy.org/k8s/pause:3.9
启动服务
kubelet.service
cri-docker.service
[root@master ~]# kubeadm token create --print-join-command
[root@node1 ~]# kubeadm join 172.25.254.200:6443 --token lma300.jusxu3igmuk5dfym --discovery-token-ca-cert-hash sha256:e107ffc608928f2337bf7742bc9b3024c6f7e179a15af2233e8092ae57c68a99 --cri-socket=unix:///var/run/cri-dockerd.sock
[root@node2 ~]# kubeadm join 172.25.254.200:6443 --token lma300.jusxu3igmuk5dfym --discovery-token-ca-cert-hash sha256:e107ffc608928f2337bf7742bc9b3024c6f7e179a15af2233e8092ae57c68a99 --cri-socket=unix:///var/run/cri-dockerd.sock
[root@master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master.txy.org Ready control-plane 64m v1.30.0
node1.txy.org Ready <none> 32m v1.30.0
node2.txy.org Ready <none> 32m v1.30.0
# 测试集群运行情况
[root@master ~]# kubectl run test --image nginx #建立一个pod
pod/test created
[root@master ~]# kubectl get pods #查看pod状态
这个阶段如果生成的集群token找不到了可以重新生成
# 重新做集群
[root@master ~]# kubectl delete nodes k8s-node1.txy.org
[root@master ~]# kubectl delete nodes k8s-node2.txy.org
[root@master ~]# kubeadm reset --cri-socket=unix:///var/run/cri-dockerd.sock
# 重新做初始化集群
[root@master ~]# kubeadm init --pod-network-cidr=10.244.0.0/16 \
--image-repository reg.txy.org/k8s \
--kubernetes-version v1.30.0 \
--cri-socket=unix:///var/run/cri-dockerd.sock
[root@master ~]# vim kube-flannel.yml # 修改image
[root@master ~]# kubectl apply -f kube-flannel.yml
[root@node1 ~]# kubeadm reset --cri-socket=unix:///var/run/cri-dockerd.sock
[root@node2 ~]# kubeadm reset --cri-socket=unix:///var/run/cri-dockerd.sock
# 再重新将节点加入集群
[root@node1 ~]# kubeadm join 172.25.254.200:6443 --token lma300.jusxu3igmuk5dfym --discovery-token-ca-cert-hash sha256:e107ffc608928f2337bf7742bc9b3024c6f7e179a15af2233e8092ae57c68a99 --cri-socket=unix:///var/run/cri-dockerd.sock
[root@node2 ~]# kubeadm join 172.25.254.200:6443 --token lma300.jusxu3igmuk5dfym --discovery-token-ca-cert-hash sha256:e107ffc608928f2337bf7742bc9b3024c6f7e179a15af2233e8092ae57c68a99 --cri-socket=unix:///var/run/cri-dockerd.sock
[root@master ~]# kubectl get nodes
三、pod管理与优化
3.1 常用的Pod基础命令
列出所有命名空间中的所有Pod↓
kubectl get pods --all-namespaces
列出指定命名空间中的所有Pod
kubectl get pods -n <namespace>
显示指定Pod的详细信息,包括状态、事件等
kubectl describe pod <pod-name> -n <namespace>
显示指定Pod的日志
kubectl logs <pod-name> -n <namespace>
实时显示指定Pod的日志
kubectl logs -f <pod-name> -n <namespace>
指定Pod中执行命令,例如进入Pod的终端
kubectl exec -it <pod-name> -n <namespace> -- <command>
根据指定的YAML文件创建Pod
kubectl apply -f pod.yaml
删除指定的Pod
kubectl delete pod <pod-name> -n <namespace>
将指定Pod的配置导出为YAML文件
kubectl get pod <pod-name> -n <namespace> -o yaml > pod-config.yaml
列出当前命名空间中的所有Pod
kubectl get pods
列出指定命名空间中的所有Pod
kubectl get pods -n <namespace>
显示Pod的网络配置信息,包括IP地址和所在的Node
kubectl get pod -o wide
3.2 Pod基本配置
Pod的基本配置包括定义Pod的名称、容器镜像、端口、环境变量等。以下是一个简单的Pod配置示例:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: nginx:latest
ports:
- containerPort: 80
env:
- name: MY_POD_NAME
value: "my-pod"
- name: MY_CPU_REQUEST
value: "500m"
在这个示例中,我们定义了一个名为my-pod
的Pod,其中包含一个名为my-container
的容器,使用nginx:latest
镜像,并暴露80端口。同时,我们设置了两个环境变量MY_POD_NAME和
MY_CPU_REQUEST
。
3.3 多容器Pod配置示例
一个包含多个容器的Pod配置可能如下所示:
apiVersion: v1
kind: Pod
metadata:
name: multi-container-pod
spec:
containers:
- name: container1
image: nginx:latest
ports:
- containerPort: 80
- name: container2
image: busybox:latest
command: ["sleep", "3600"]
这个配置文件定义了一个名为multi-container-pod
的Pod,其中包含两个容器:container1
使用nginx:latest
镜像,container2
使用busybox:latest
镜像并运行一个无限期的睡眠命令。
3.4 镜像拉取策略
Kubernetes允许用户设置镜像拉取策略,以控制容器镜像的拉取行为。例如,可以设置为Always
、IfNotPresent
或Never
。
spec:
containers:
- name: my-container
image: nginx:latest
imagePullPolicy: Always
在这个示例中,我们设置了镜像拉取策略为Always
,表示每次启动Pod时都会尝试拉取最新的镜像。
3.5 命令设置
Pod中的容器可以设置启动命令和参数。例如:
spec:
containers:
- name: my-container
image: busybox
command: ["sleep"]
args: ["3600"]
3.6 端口设置
Pod中的容器可以暴露多个端口,以便与其他服务通信。例如:
spec:
containers:
- name: my-container
image: nginx:latest
ports:
- containerPort: 80
- containerPort: 443
在这个示例中,我们定义了两个端口:80和443,分别用于HTTP和HTTPS通信。
3.7 使用ReplicaSet管理Pod
根据,可以使用ReplicaSet来管理Pod的副本数量:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: example-replicaset
spec:
replicas: 3
selector:
matchLabels:
app: example
template:
metadata:
labels:
app: example
spec:
containers:
- name: example-container
image: nginx:latest
ports:
- containerPort: 80
这个配置文件定义了一个名为example-replicaset
的ReplicaSet,确保集群中始终运行3个Pod副本。
3.8 使用Deployment管理Pod
根据,可以使用Deployment来管理Pod的部署和更新:
apiVersion: apps/v1
kind: Deployment
metadata:
name: example-deployment
spec:
replicas: 3
selector:
matchLabels:
app: example
template:
metadata:
labels:
app: example
spec:
containers:
- name: example-container
image: nginx:latest
ports:
- containerPort: 80
这个配置文件定义了一个名为example-deployment
的Deployment,确保集群中始终运行3个Pod副本,并支持滚动更新和回滚。
3.9 资源管理
Kubernetes允许用户为Pod中的容器设置资源请求和限制,以确保容器在运行时有足够的资源。例如:
spec:
containers:
- name: my-container
image: nginx:latest
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
在这个示例中,我们为容器设置了内存和CPU的请求和限制。
3.10 环境变量设置
Pod中的容器可以设置环境变量,以便在运行时使用。例如:
spec:
containers:
- name: my-container
image: nginx:latest
env:
- name: MY_POD_NAME
value: "my-pod"
- name: MY_CPU_REQUEST
value: "500m"
在这个示例中,我们设置了两个环境变量MY_POD_NAME
和MY_CPU_REQUEST
,分别用于传递Pod名称和CPU请求。
3.11 Pod管理策略
Kubernetes提供了多种Pod管理策略,如滚动更新、并行更新等。例如,使用StatefulSet管理Pod时,可以设置Pod管理策略:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: my-statefulset
spec:
serviceName: "nginx"
replicas: 3
podManagementPolicy: Parallel
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
name: web
在这个示例中,我们使用StatefulSet管理Pod,并设置了Pod管理策略为Parallel
,表示并行启动和终止Pod。
3.12 Pod调度管理
Kubernetes通过调度器(Scheduler)将Pod调度到合适的节点上运行。可以通过设置节点标签和亲和性规则来控制Pod的调度位置。例如:
spec:
containers:
- name: my-container
image: nginx:latest
nodeSelector:
disktype: ssd
在这个示例中,我们通过nodeSelector
指定了Pod只能调度到具有disktype=ssd
标签的节点上。
3.13 Pod监控与日志管理
Kubernetes提供了多种工具来监控和管理Pod的日志。例如,可以使用kubectl logs
命令查看Pod的日志:
kubectl logs my-pod
这个命令将显示名为my-pod
的Pod的日志输出。
3.14 Pod删除与更新
Kubernetes允许用户通过kubectl delete
命令删除Pod,并通过控制器(如Deployment、StatefulSet)进行Pod的更新。例如:
kubectl delete pod my-pod
这个命令将删除名为my-pod
的Pod。