# k8s入门讲解

> 作者/来源: UCloud 运营管理员
> 发布时间: 2023-01-11T05:20:00.000Z
> 分类: 解决方案
> 标签: AI, 数据库, Kubernetes
> 原文链接: http://117.50.162.249:3000/yun/articles/1348

---

# k8s入门讲解

> 来源: https://www.ucloud.cn/yun/129561.html
> 作者: IT那活儿
> 发布日期: 发布于2023-01-11 13:20

k8s入门讲解

## **点击上方“IT那活儿”，关注后了解更多内容，不管IT什么活儿，干就完了！！！**

**K8S原理以及概念**

**1. 基本概念**

Kubernetes开源的，用于管理云平台中多个主机上的容器化的应用，Kubernetes目标是让部署容器化的应用简单并且高效（powerful,Kubernetes维护的一种机制）。

![](https://ucloud-blog.cn-bj.ufileos.com/articles/129561/images/129561_000.png)

**1.1  Kubernetes 特点**

- 可移植: 支持公有云，私有云，混合云，多重云（multi-cloud）；
- 可扩展: 模块化, 插件化, 可挂载, 可组合；
- 自动化: 自动部署，自动重启，自动复制，自动伸缩/扩展；
- 快速部署应用，快速扩展应用；
- 无缝对接新的应用功能；
- 节省资源，优化硬件资源的使用。

![](https://ucloud-blog.cn-bj.ufileos.com/articles/129561/images/129561_001.png)

k8s：核心架构图

**2. K8S**组件

**1）APIserver**

所有服务的统一入口。

**2）Controllermanager**

维持副本期望数目。

**3）sureduler**

负责介绍任务，选择合适的节点运行。

**4）etcd**

键值对数据库，储存k8s集群所有的重要信息（持久化）。

**5）coredns**

可以为集群中svc创建一个域名ip的对应关系解析。

**6）dashboard**

给k8s集群提供一个B/S结构访问体系（浏览器与服务器架构模式）。

**7）imgress controller**

官方k8s集群只能实现四层代理，imgress可以实现七层代理，也就是可以根据主机名，域名进行负载均衡。

k8s通常不会直接创建pod,而是通过controller来管理pod的。controller中定义了pod的部署特性，比如有几个剧本，在什么样的node上运行等。为了满足不同的业务场景，k8s提供了多种controller，包括deployment、replicaset、daemonset、statefulset、job等。

- deployment

#是最常用的controller deployment可以管理pod的多个副本，并确保pod按照期望的状态运行。

- replicaset

#实现了pod的多副本管理。使用deployment时会自动创建replicaset，也就是说deployment是通过replicaset来管理pod的多个副本的，我们通常不需要直接使用replicaset。

- daemonset

#用于每个node最多只运行一个pod副本的场景。正如其名称所示的，daemonset通常用于运行daemon。

- statefuleset

#能够保证pod的每个副本在整个生命周期中名称是不变的，而其他controller不提供这个功能。当某个pod发生故障需要删除并重新启动时，pod的名称会发生变化，同时statefulset会保证副本按照固定的顺序启动、更新或者删除。

- job

#用于运行结束就删除的应用，而其他controller中的pod通常是长期持续运行的。

**8）service**

k8s的 service定义了外界访问一组特定pod的方式。service有自己的IP和端口，service为pod提供了负载均衡。k8s运行容器pod与访问容器这两项任务分别由controller和service执行。

**Service 有四种类型：**

- ClusterIP：默认类型，自动分配一个仅 cluster 内部可以访问的虚拟 IP。
- NodePort：在 ClusterIP 基础上为 Service 在每台机器上绑定一个端口，这样就可以通过NodeIP:NodePort 来访问该服务。如果 kube-proxy 设置了 –nodeport-addresses=10.240.0.0/16（v1.10 支持），那么仅该 NodePort 仅对设置在范围内的 IP 有效。
- LoadBalancer：在 NodePort 的基础上，借助 cloud provider 创建一个外部的负载均衡器，并将请求转发到 :NodePort。
- ExternalName：将服务通过 DNS CNAME 记录方式转发到指定的域名（通过 spec.externlName 设定）。需要 kube-dns 版本在 1.7 以上。

**9）namespace**

可以将一个物理的cluster逻辑上划分成多个虚拟cluster，每个cluster就是一个namespace。不同的namespace里的资源是完全隔离的。

k8s的集群部署

**1. 基础环境配置**

#修改host。

```
vim /etc/hosts10.0.0.50 k8s-master10.0.0.51 k8s-node-0110.0.0.52 k8s-node-02
```

#修改 10.0.0.50 服务器，设置 hostname，然后将 hostname 写入 hosts。

```
$ hostnamectl set-hostname k8s-master$ echo "127.0.0.1 $(hostname)" >> /etc/hosts
```

#修改 10.0.0.51 服务器，设置 hostname，然后将 hostname 写入 hosts。

```
$ hostnamectl set-hostname k8s-node-01$ echo "127.0.0.1 $(hostname)" >> /etc/hosts
```

#修改 10.0.0.52 服务器，设置 hostname，然后将 hostname 写入 hosts。

```
$ hostnamectl set-hostname k8s-node-02$ echo "127.0.0.1 $(hostname)" >> /etc/hosts
```

#时间同步：

```
systemctl start chronyd.service && systemctl enable chronyd.service
```

#关闭防火墙：

```
systemctl stop firewalld && systemctl disable firewalld
```

#关闭selinux：

```
setenforce 0sed -i s/^SELINUX=enforcing$/SELINUX=disabled/ /etc/selinux/config
```

#禁用swap：

```
swapoff -a && sysctl -w vm.swappiness=0vi /etc/fstab#/dev/mapper/centos-swap swap swap defaults 0 0
```

#配置内核参数：

```
$ cat < /etc/sysctl.d/k8s.confnet.ipv4.ip_forward = 1net.bridge.bridge-nf-call-ip6tables = 1net.bridge.bridge-nf-call-iptables = 1net.ipv4.tcp_keepalive_time = 600net.ipv4.tcp_keepalive_intvl = 30net.ipv4.tcp_keepalive_probes = 10EOF
```

**#使配置生效：**

#挂载 br\_netfilter：

```
$ modprobe br_netfilter
```

#使配置生效：

```
$ sysctl -p /etc/sysctl.d/k8s.conf
```

#查看是否生成相关文件：

```
$ ls /proc/sys/net/bridge
```

#由于ipvs已经加入到了内核的主干，所以为kube-proxy开启ipvs的前提需要加载以下的内核模块：

```
ip_vsip_vs_rrip_vs_wrrip_vs_shnf_conntrack_ipv4$ cat > /etc/sysconfig/modules/ipvs.modules <#!/bin/bashmodprobe -- ip_vsmodprobe -- ip_vs_rrmodprobe -- ip_vs_wrrmodprobe -- ip_vs_shmodprobe -- nf_conntrack_ipv4EOF
```

**#执行脚本并查看是否正常加载内核模块：**

#修改脚本权限：

```
$ chmod 755 /etc/sysconfig/modules/ipvs.modules
```

#执行脚本：

```
$ bash /etc/sysconfig/modules/ipvs.modules
```

#查看是否已经正确加载所需的内核模块：

```
$ lsmod | grep -e ip_vs -e nf_conntrack_ipv4
```

#安装 ipset 和 ipvsadm：

```
$ yum install -y ipset ipvsadm
```

#配置资源限制：

```
echo "* soft nofile 65536" >> /etc/security/limits.confecho "* hard nofile 65536" >> /etc/security/limits.confecho "* soft nproc 65536" >> /etc/security/limits.confecho "* hard nproc 65536" >> /etc/security/limits.confecho "* soft memlock unlimited" >> /etc/security/limits.confecho "* hard memlock unlimited" >> /etc/security/limits.conf
```

#安装依赖包以及相关工具：

```
yum install -y epel-releaseyum install -y yum-utils device-mapper-persistent-data lvm2 net-tools conntrack-tools wget vim ntpdate libseccomp libtool-ltdl
```

#由于官方下载速度比较慢，所以需要更改 Docker 安装的 yum 源，这里推荐用阿里镜像源：

```
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
```

#安装指定版本 docker：

#注意：安装前一定要提前查询将要安装的 Kubernetes 版本是否和 Docker 版本对应。

```
yum install -y docker-ce-18.09.9-3.el7
```

#设置镜像存储目录，找到大点的挂载的目录进行存储：

```
$ vi /lib/systemd/system/docker.service
```

#找到这行，往后面加上存储目录，例如这里是 --graph /apps/docker：

```
ExecStart=/usr/bin/docker --graph /apps/docker
```

#配置 Docker 参数和镜像加速器：

```
mkdir -p /etc/dockercat > /etc/docker/daemon.json << EOF{"exec-opts": ["native.cgroupdriver=systemd"],"registry-mirrors": ["https://dockerhub.azk8s.cn","http://hub-mirror.c.163.com","https://registry.docker-cn.com"],"storage-driver": "overlay2","storage-opts": ["overlay2.override_kernel_check=true"],"log-driver": "json-file","log-opts": {"max-size": "100m","max-file":"5"}}EOF
```

#启动 Docker：

```
$ systemctl start docker && systemctl enable docker
```

**2. 安装 kubelet、kubectl、kubeadm（全部节点）**

- kubelet: 在集群中的每个节点上用来启动 pod 和 container 等；
- kubectl: 用来与集群通信的命令行工具；
- kubeadm: 用来初始化集群的指令。

**注意安装顺序，**一定不要先安装 kubeadm，因为 kubeadm 会自动安装最新版本的 kubelet 与kubectl，导致版本不一致问题。

#安装 kubelet：

```
yum install -y kubelet-1.16.3-0
```

#安装 kubectl：

```
yum install -y kubectl-1.16.3-0
```

#安装 kubeadm：

```
yum install -y kubeadm-1.16.3-0
```

#启动 kubelet 并配置开机启动：

```
systemctl start kubelet && systemctl enable kubelet
```

#重启全部节点：

```
reboot
```

**3. kubeadm 安装 kubernetes（Master 节点）**

创建 kubeadm 配置文件 kubeadm-config.yaml，然后需要配置一些参数：

- 配置 localAPIEndpoint.advertiseAddress 参数，调整为你的 Master 服务器地址；
- 配置 imageRepository 参数，调整 kubernetes 镜像下载地址为阿里云；
- 配置 networking.podSubnet 参数，调整为你要设置的网络范围。

**kubeadm-config.yaml**

```
$ cat > kubeadm-config.yaml << EOFapiVersion: kubeadm.k8s.io/v1beta2kind: InitConfigurationlocalAPIEndpoint:advertiseAddress: 10.0.0.50bindPort: 6443nodeRegistration:taints:- effect: PreferNoSchedulekey: node-role.kubernetes.io/master---apiVersion: kubeadm.k8s.io/v1beta2kind: ClusterConfigurationimageRepository: registry.aliyuncs.com/google_containerskubernetesVersion: v1.16.3networking:podSubnet: 10.244.0.0/16serviceSubnet: 10.96.0.0/12---apiVersion: kubeproxy.config.k8s.io/v1alpha1kind: KubeProxyConfigurationmode: ipvsEOF
```

**kubeadm 初始化 kubernetes 集群：**

```
kubeadm init --config kubeadm-config.yaml
```

**部署日志信息：**

```
......[addons] Applied essential addon: CoreDNS[addons] Applied essential addon: kube-proxyYour Kubernetes control-plane has initialized successfully!To start using your cluster, you need to run the following as a regular user:mkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/configYou should now deploy a pod network to the cluster.Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:https://kubernetes.io/docs/concepts/cluster-administration/addons/Then you can join any number of worker nodes by running the following on each asroot:kubeadm join 192.168.2.11:6443 --token 4udy8a.f77ai0zun477kx0p --discovery-token-ca-cert-hashsha256:4645472f24b438e0ecf5964b6dcd64913f68e0f9f7458768cfb96a9ab16b4212
```

**在此处看日志可以知道，可以通过下面命令，添加 kubernetes 相关环境变量：**

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

**工作节点加入集群（Work Node 节点）：**

根据上面 Master 节点创建 Kubernetes 集群时的日志信息，可以知道在各个节点上执行下面命令来让工作节点加入主节点：

```
$ kubeadm join 192.168.2.11:6443 --token 4udy8a.f77ai0zun477kx0p --discovery-token-ca-cert-hashsha256:4645472f24b438e0ecf5964b6dcd64913f68e0f9f7458768cfb96a9ab16b4212
```

如果上面 token 过期，则可以通过 kubeadm token create --print-join-command 命令重新获取加入集群的指令。

**4. 部署 Calico 网络插件**

下载 Calico 部署文件，并替换里面的网络范围为上面 kubeadm 中 networking.podSubnet 配置的值。

#下载 calico 部署文件：

```
$ wget https://docs.projectcalico.org/v3.10/getting-started/kubernetes/installation/hosted/kubernetes-datastore/calico-networking/1.7/calico.yaml
```

#替换 calico 部署文件的 IP 为 kubeadm 中的 networking.podSubnet 参数 10.244.0.0。

```
sed -i s/192.168.0.0/10.244.0.0/g calico.yaml
```

#部署 Calico 插件：

```
kubectl apply -f calico.yaml
```

#查看是否部署成功。

```
kubectl get pod -n kube-system
```

**5. 配置 Kubectl 命令自动补全（Master 节点）**

安装补全工具：

```
yum install -y bash-completion
```

添加补全配置：

```
source /usr/share/bash-completion/bash_completionsource <(kubectl completion bash)echo "source <(kubectl completion bash)" >> ~/.bashrc
```

添加完成就可与通过输入 kubectl 后，按补全键（一般为 tab）会自动补全对应的命令。

k8s的组件部署以及使用

**1. 基本概念**

![](https://ucloud-blog.cn-bj.ufileos.com/articles/129561/images/129561_002.png)

**1）Ingress**

其中，Ingress资源通过yaml文件申明规则配置。

**2）Ingress Controller**

Ingress Controller 就是一个反向代理程序，它负责解析 Ingress 的反向代理规则，以Pod的形式运行，监控apiserver的/ingress端口后的backend services，如果 Ingress 有增删改的变动，所有的 Ingress Controller 都会及时更新自己相应的转发规则，当 Ingress Controller 收到请求后就会根据这些规则将请求转发到对应的 Service。

核心是一个deployment，实现方式有很多，比如nginx, Contour, Haproxy, trafik, Istio，需要编写的yaml有：Deployment, Service, ConfigMap, ServiceAccount（Auth），其中service的类型可以是NodePort或者LoadBalancer。

**2. 组件部署**

为了让Ingress Controller正常启动，需要给它配置一个默认的backend，用于当客户端访问的URL地址不存在时，能够返回一个正确的404应答。

```
apiVersion: extensions/v1beta1kind: Deploymentmetadata:name: default-http-backendlabels:k8s-app: default-http-backendnamespace: kube-systemspec:replicas: 1template:metadata:labels:k8s-app: default-http-backendspec:terminationGracePeriodSeconds: 60containers:- name: default-http-backend # Any image is permissable as long as:# 1. It serves a 404 page at /# 2. It serves 200 on a /healthz endpointimage: 192.168.121.140:5000/defaultbackendlivenessProbe:httpGet:path: /healthzport: 8080scheme: HTTPinitialDelaySeconds: 30timeoutSeconds: 5ports:- containerPort: 8080resources:limits:cpu: 10mmemory: 20Mirequests:cpu: 10mmemory: 20Mi---apiVersion: v1kind: Servicemetadata:name: default-http-backendnamespace: kube-systemlabels:k8s-app: default-http-backendspec:ports:- port: 80targetPort: 8080selector:k8s-app: default-http-backend
```

创建backend：

```
kubectl apply -f default-backend.yaml
```

下载deploy.yaml：

```
#访问网站下载文件https://github.com/kubernetes/ingress-nginx/blob/controller-v0.48.1/deploy/static/provider/baremetal/deploy.yaml
```

看看pod是否正常启动：

```
kubectl get pods -n ingress-nginx
```

创建ingress：

```
#ingress_test.yamlapiVersion: extensions/v1beta1 kind: Ingressmetadata:name: ingress-testannotations:kubernetes.io/ingress.class: "nginx"# 开启use-regex，启用path的正则匹配nginx.ingress.kubernetes.io/use-regex: "true"spec:rules:# 定义域名- host: test.ingress.comhttp:paths:# 不同path转发到不同端口- path: /backend:serviceName: nginx-controllerservicePort: 8000
```

创建ingress：

```
kubectl apply -f ingress_test.yaml
```

创建nginx软件服务：

```
vim nginx-rc.yamlapiVersion: v1kind: Deploymentmetadata:name: nginx-controllerspec:replicas: 2selector:name: nginxtemplate:metadata:labels:name: nginxspec:containers:- name: nginximage: nginxports:- containerPort: 80cat nginx-server-nodeport.yamlapiVersion: v1kind: Servicemetadata:name: nginx-service-nodeportspec:ports:- port: 8000targetPort: 80protocol: TCPtype: NodePort selector:name: nginx#创建pod以及servicekubectl apply -f nginx-rc.yamlkubectl apply -f nginx-server-nodeport.yaml
```

通过curl访问对应nginx：

```
curl -i test.ingress.comHTTP/1.1 200 OK
```

![](https://ucloud-blog.cn-bj.ufileos.com/articles/129561/images/129561_003.png)

## 本文作者：王文权

## 本文来源：IT那活儿（上海新炬王翦团队）

![](https://ucloud-blog.cn-bj.ufileos.com/articles/129561/images/129561_004.png)