服务器-Kubernetes (K8S)单机部署实战 -- 001
本篇博文是 centos 7 系统安装 kubernetes 单机 master 节点操作。
一: 查看 服务器 配置信息
1. 执行命令查看服务器cpu信息。安装 kubernetes 服务,cpu核心数必须大于2,内存大于2G。
lscpu
2. 修改服务器设置信息,避免安装出现问题。
a. 临时关闭swap,防止 执行 kubeadm 命令爆错。
swapoff -a
b. 临时关闭 selinux,减少不必要的配置。
setenforce 0
c. 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
d. 设置网桥信息
cat << EOF > /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 EOF
e. 修改 主机名为 master
hostnamectl set-hostname master
f. 修改 hosts 文件,设置 master 主机名称和本机IP 映射关系
10.0.0.206 master
二: 安装并配置 docker
1. 安装必须工具
yum install -y yum-utils device-mapper-persistent-data lvm2
2. 添加 阿里云 yum 仓库 repo
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
3. 安装 docker
yum -y install docker-ce
4. 修改 docker 的 /etc/docker/daemon.json 文件。如果文件不存在,则创建新的。
a. 设置 阿里云国内 docker 源
b. 设置 cgroupdriver 为 systemd
sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://xcjha0pw.mirror.aliyuncs.com"], "exec-opts": ["native.cgroupdriver=systemd"] } EOF
5. 修改完后,使用新配置 重启 docker 服务。
sudo systemctl daemon-reload
sudo systemctl restart docker
6. 设置 docker 服务开机自启动
systemctl enable docker
7. 生成 containerd 配置信息,并修改 两处相关配置。
# 生成 containerd 的默认配置文件
containerd config default > /etc/containerd/config.toml
a. 修改1 修改 sandbox_image 镜像配置,改为阿里镜像。
# 查看 sandbox 的默认镜像仓库在文件中的第几行
cat /etc/containerd/config.toml | grep -n "sandbox_image"
# 使用 vim 编辑器 定位到 sandbox_image,将 仓库地址修改成 阿里镜像
vim /etc/containerd/config.toml
sandbox_image = " registry.aliyuncs.com/google_containers/pause:3.6"
b. 修改2 注释掉 cri 插件,否则 kubelet 无法启动。
sed -i -r '/cri/s/(.*)/#\1/' /etc/containerd/config.toml systemctl restart containerd
# 重启 containerd 服务
systemctl daemon-reload
systemctl restart containerd
三:kubernetes 安装操作步骤
1. 配置 kubernetes 下载源。使用国内阿里云 yum源
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
2. 安装 kubernetes 服务的相关应用 kubectl, kubeadm, kubectl
kubelet: 运行在 cluster, 负责启动 pod,并管理容器。
kubeadm: kubernetes 快速构建工具,用于初始化 cluster。
kubectl: kubernetes 命令工具。进行服务的部署和管理。
yum install -y --nogpgcheck kubelet-1.28.2 kubeadm-1.28.2 kubectl-1.28.2
3. 查看安装结果
kubelet --version
kubectl version
kubeadm version
4. 启动 kubelet 服务
systemctl daemon-reload
systemctl start kubelet
systemctl enable kubelet
5. 生成 kubernetes 初始化配置文件 init-config.yaml, 并根据实际情况修改 3 处
apiVersion: kubeadm.k8s.io/v1beta3 bootstrapTokens: - groups: - system:bootstrappers:kubeadm:default-node-token token: abcdef.0123456789abcdef ttl: 24h0m0s usages: - signing - authentication kind: InitConfiguration localAPIEndpoint: advertiseAddress: 10.0.0.206 //修改1 master节点IP地址 可cat /etc/hosts 看到 bindPort: 6443 nodeRegistration: criSocket: /var/run/dockershim.sock imagePullPolicy: IfNotPresent name: master //修改2 master节点node的名称 taints: null --- apiServer: timeoutForControlPlane: 4m0s apiVersion: kubeadm.k8s.io/v1beta3 certificatesDir: /etc/kubernetes/pki clusterName: kubernetes controllerManager: {} dns: {} etcd: local: dataDir: /var/lib/etcd imageRepository: registry.aliyuncs.com/google_containers //修改3 修改为阿里云地址 kind: ClusterConfiguration
kubernetesVersion: 1.28.0 networking: dnsDomain: cluster.local serviceSubnet: 10.96.0.0/12 scheduler: {}
6. 下载 kubernetes 相关镜像
注意执行目录在 init-config.yaml 文件目录
kubeadm config images pull --config=init-config.yaml
当镜像拉取失败,通过命令获取所有需要的镜像,然后一个个拉取
kubeadm config images list --config init-config.yaml
结果如下(不同版本有差别):
registry.aliyuncs.com/google_containers/kube-apiserver:v1.28.0
registry.aliyuncs.com/google_containers/kube-controller-manager:v1.28.0
registry.aliyuncs.com/google_containers/kube-scheduler:v1.28.0
registry.aliyuncs.com/google_containers/kube-proxy:v1.28.0
registry.aliyuncs.com/google_containers/pause:3.9
registry.aliyuncs.com/google_containers/etcd:3.5.9-0
registry.aliyuncs.com/google_containers/coredns:v1.10.1
7. 运行 kubeadm 初始化操作,进行master 节点安装
kubeadm init --apiserver-advertise-address=10.0.0.206 --apiserver-bind-port=6443 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12 --kubernetes-version=1.28.2 --image-repository registry.aliyuncs.com/google_containers
8. 如果安装失败,重置集群初始化,然后再执行 7 步骤。
kubeadm reset
9. 在 master 节点服务执行如下命令,进行 管理员信息配置,方便获取 token 信息。
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
当重置集群后,需同步删除 $HOME/.kube 目录
rm -rf $HOME/.kube
10. 当需要在 master 节点上布署服务时(启动pod),则需要修改master 节点污点配置
查看污点信息:
kubectl describe node master |grep Taints
结果: Taints: node-role.kubernetes.io/control-plane:NoSchedule
去除污点NoSchedule,最后一个"-"代表删除
kubectl taint nodes master node-role.kubernetes.io/control-plane:NoSchedule-
备注:
NoSchedule : 一定不被调度 但是不会驱逐已有的 这个部署 ingress-controller 的时候 有用
PreferNoSchedule : 尽量不被调度
NoExecute : 不会调度,并且还会驱逐Node已有Pod 这个很坏
11. 修改 kubernetes 布署服务时,使用的端口范围。如果不需要调整,可以不用修改。
k8s的node节点的端口默认被限制在30000-32767的范围
编辑 kube-apiserver.yaml文件
vi /etc/kubernetes/manifests/kube-apiserver.yaml
在spec.containers.command的最后面加上
- --service-node-port-range=1-65535
重启 kubelet
systemctl daemon-reload
systemctl restart kubelet
12. 部署网络插件 kube-flannel
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl apply -f kube-flannel.yml
如果 wget 下载失败,则新建 kube-flannel.yml, 并复制如下内容。
--- kind: Namespace apiVersion: v1 metadata: name: kube-flannel labels: pod-security.kubernetes.io/enforce: privileged --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: flannel rules: - apiGroups: - "" resources: - pods verbs: - get - apiGroups: - "" resources: - nodes verbs: - list - watch - apiGroups: - "" resources: - nodes/status verbs: - patch --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: flannel roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: flannel subjects: - kind: ServiceAccount name: flannel namespace: kube-flannel --- apiVersion: v1 kind: ServiceAccount metadata: name: flannel namespace: kube-flannel --- kind: ConfigMap apiVersion: v1 metadata: name: kube-flannel-cfg namespace: kube-flannel labels: tier: node app: flannel data: cni-conf.json: | { "name": "cbr0", "cniVersion": "0.3.1", "plugins": [ { "type": "flannel", "delegate": { "hairpinMode": true, "isDefaultGateway": true } }, { "type": "portmap", "capabilities": { "portMappings": true } } ] } net-conf.json: | { "Network": "10.244.0.0/16", "Backend": { "Type": "vxlan" } } --- apiVersion: apps/v1 kind: DaemonSet metadata: name: kube-flannel-ds namespace: kube-flannel labels: tier: node app: flannel spec: selector: matchLabels: app: flannel template: metadata: labels: tier: node app: flannel spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/os operator: In values: - linux hostNetwork: true priorityClassName: system-node-critical tolerations: - operator: Exists effect: NoSchedule serviceAccountName: flannel initContainers: - name: install-cni-plugin #image: flannelcni/flannel-cni-plugin:v1.1.0 for ppc64le and mips64le (dockerhub limitations may apply) image: docker.io/rancher/mirrored-flannelcni-flannel-cni-plugin:v1.1.0 command: - cp args: - -f - /flannel - /opt/cni/bin/flannel volumeMounts: - name: cni-plugin mountPath: /opt/cni/bin - name: install-cni #image: flannelcni/flannel:v0.20.0 for ppc64le and mips64le (dockerhub limitations may apply) image: docker.io/rancher/mirrored-flannelcni-flannel:v0.20.0 command: - cp args: - -f - /etc/kube-flannel/cni-conf.json - /etc/cni/net.d/10-flannel.conflist volumeMounts: - name: cni mountPath: /etc/cni/net.d - name: flannel-cfg mountPath: /etc/kube-flannel/ containers: - name: kube-flannel #image: flannelcni/flannel:v0.20.0 for ppc64le and mips64le (dockerhub limitations may apply) image: docker.io/rancher/mirrored-flannelcni-flannel:v0.20.0 command: - /opt/bin/flanneld args: - --ip-masq - --kube-subnet-mgr resources: requests: cpu: "100m" memory: "50Mi" limits: cpu: "100m" memory: "50Mi" securityContext: privileged: false capabilities: add: ["NET_ADMIN", "NET_RAW"] env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: EVENT_QUEUE_DEPTH value: "5000" volumeMounts: - name: run mountPath: /run/flannel - name: flannel-cfg mountPath: /etc/kube-flannel/ - name: xtables-lock mountPath: /run/xtables.lock volumes: - name: run hostPath: path: /run/flannel - name: cni-plugin hostPath: path: /opt/cni/bin - name: cni hostPath: path: /etc/cni/net.d - name: flannel-cfg configMap: name: kube-flannel-cfg - name: xtables-lock hostPath: path: /run/xtables.lock type: FileOrCreate
三:检查 kubernetes 布署是否成功
kubectl cluster-info:查看 k8s 集群信息,包括 API Server 的地址和版本以及控制平面组件的状态。
kubectl get nodes:查看集群中的节点信息,包括节点名称、IP 地址、状态和运行时间等。
kubectl get pods:查看当前命名空间下的 Pod 信息,包括 Pod 名称、所属节点、容器状态、IP 地址等。
kubectl get pods,svc -o wide --all-namespaces : 查看 所有命名空间的 pods,svc 信息
kubectl get cs : 查看集群健康状态
kubectl describe service/kubernetes
四. kubernetes 常见问题
问题一:
-- The start-up result is done. Feb 02 20:51:43 master kubelet[14025]: E0202 20:51:43.774113 14025 run.go:74] "command failed" err="failed to load kubelet config file, path: /var/lib/kubelet/config.yaml, error: failed to load Kubelet config file /var/lib/kubelet/config.yaml, error failed to read kubelet config file \"/var/lib/kubelet/config.yaml\", error: open /var/lib/kubelet/config.yaml: no such file or directory" Feb 02 20:51:43 master systemd[1]: kubelet.service: main process exited, code=exited, status=1/FAILURE Feb 02 20:51:43 master systemd[1]: Unit kubelet.service entered failed state. Feb 02 20:51:43 master systemd[1]: kubelet.service failed.
containerd 配置没修改。修改后,重启服务即可。
sed -i -r '/cri/s/(.*)/#\1/' /etc/containerd/config.toml systemctl restart containerd
问题 二:
failed to pull and unpack image \\\"registry.k8s.io/pause:3.6\\\": failed to resolve reference
# 生成 containerd 的默认配置文件
containerd config default > /etc/containerd/config.toml
# 查看 sandbox 的默认镜像仓库在文件中的第几行
cat /etc/containerd/config.toml | grep -n "sandbox_image"
# 使用 vim 编辑器 定位到 sandbox_image,将 仓库地址修改成 阿里镜像
vim /etc/containerd/config.toml
sandbox_image = " registry.aliyuncs.com/google_containers/pause:3.6"
# 重启 containerd 服务
systemctl daemon-reload
systemctl restart containerd.service
问题三:
E0202 22:18:22.949900 3017 memcache.go:265] couldn't get current server API group list: Get "https://10.0.0.206:6443/api?timeout=32s": tls: failed to verify certificate: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "kubernetes")
当重置集群后,需同步删除 $HOME/.kube 目录
rm -rf $HOME/.kube
五. 部署 nginx 服务,检查 kubenetes 服务运行情况
1. 创建 nginx 布署文件。
kind: Namespace apiVersion: v1 metadata: name: myserver #创建namespace --- kind: Deployment apiVersion: apps/v1 #可查询它的api版本 kubectl explain deployment.apiVersion metadata: #定义pod元数据信息,可查询它的下级子字段kubectl explain deployment.metadata labels: #定义deployment控制器标签 app: nginx-deployment-label #标签名称以键值形式定义,可以定义多个,这里标签是app值为nginx-deployment-label name: nginx-deployment #deployment资源的名字 namespace: myserver #deployment所属的namespace,默认是defaule spec: #定义Deployment中容器的详细信息,可通过kubectl explain deployment.spec查询 replicas: 1 #定义创建出pod的副本数,默认值是1个pod selector: #定义标签选择器,它跟上面的Deployment标签不是一回事,它是找下面template中定义的labels标签 matchLabels: #定义匹配的标签,必须要设置 app: nginx-selector #匹配的目标标签,控制器会拿这个标签匹配下面的pod template: #定义模板,用来描述需要创建的pod作用 metadata: #定义模板元数据 labels: #这个labels会继承给这个yaml文件Deployment控制器创建的所有pod app: nginx-selector #这个labels的key是app,值是nginx-selector,它会继承给下面的pod,和上面matchLabels.app: nginx-selector一样 spec: #定义pod的详细信息 containers: #定义pod中容器列表,可以定义多个pod - name: nginx-container #容器名称 image: nginx:1.20 #容器镜像 imagePullPolicy: Always #镜像拉取策略 ports: #定义容器端口列表 - containerPort: 80 #定义一个端口 protocol: TCP #定义协议 name: http #端口名称 - containerPort: 443 protocol: TCP name: https env: #给容器传递环境变量 - name: "password" #变量名称,必须引号引起来 value: "123" #上面变量的值 - name: "age" value: "18" --- kind: Service apiVersion: v1 metadata: name: nginx-service labels: app: nginx-service-label #service资源的标签 namespace: myserver #所在的命名空间,与上面控制器必须在同一个命名空间 spec: type: NodePort #service类型是NodePort ports: #定义访问端口,一个service可以定义多个端口的映射关系 - name: http #定义协议名称 port: 80 #定义service端口,它可以和pod,node端口都不同,它是K8S中一个独立子网 protocol: TCP #定义类型 targetPort: 80 #目标pod端口,当访问宿主机30003端口时就会转达到pod的80端口 nodePort: 30003 #手动指定node节点暴露的端口,如果没有指定端口,那service会随机分配一个端口 - name: https port: 443 protocol: TCP targetPort: 443 nodePort: 30443 selector: app: nginx-selector #这个标签就是上面pod的标签,service通过这个标签来匹配对应的pod
2. 布署 nginx 服务。
kubectl apply -f nginx.yaml
3. 验证 nginx 服务启动成功。
curl http://127.0.0.1:30003 curl http://10.0.0.206:30003
4. 验证成功后,根据需要可以删除 nginx 布署信息。
查看deployment信息
kubectl get deployment -n <namespace>
删除deployment配置
kubectl delete deployment <deployment名> -n <namespace>
删除 svc 配置
kubectl delete svc svc名
kubectl delete deployment nginx-deployment -n myserver
kubectl delete svc nginx-service -n myserver
六. 布署 kubernetes-dashboard 服务,进行 kubernetes 集群管理
1. 下载 布署文件
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
2. 修改 布署文件,使本机可以访问
新增type: NodePort 和 nodePort:31443,以便能实现非本机访问
kind: Service apiVersion: v1 metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kubernetes-dashboard spec: type: NodePort ports: - port: 443 targetPort: 8443 nodePort: 31443 selector: k8s-app: kubernetes-dashboard
3. 布署服务
kubectl apply -f recommended.yaml
4. 创建登录用户信息
Dashboard 支持 Kubeconfig 和 Token 两种认证方式,暂时选择Token认证方式登录。
a. 创建dashboard-adminuser.yaml 文件
cat > dashboard-adminuser.yaml << EOF apiVersion: v1 kind: ServiceAccount metadata: name: admin-user namespace: kubernetes-dashboard --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: admin-user roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: admin-user namespace: kubernetes-dashboard > EOF
b. 执行命令创建用户
kubectl apply -f dashboard-adminuser.yaml
5. 获取 token,进行 服务登录。
kubectl -n kubernetes-dashboard create token admin-user
#生成过期时间为24小时的token
kubectl -n kubernetes-dashboard create token admin-user --duration=86400s
待定...