docker · 2022-05-22 0

k8s搭建及使用

一、环境

系统版本:ubuntu 18.04

有三台主机,并在 /etc/hosts中配置:

192.168.2.141 kube-master-pc
192.168.2.151 kube-work-1-pc
192.168.2.152 kube-work-2-pc

二、安装 docker

每台主机都安装 docker

apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
apt install docker-ce docker-ce-cli containerd.io

把当前用户添加到 docker 用户组

  sudo gpasswd -a $USER docker
  newgrp docker
  service docker restart

三、安装 k8s

1.关闭 swap

暂时关闭

sudo swapoff -a

永久关闭

# 注释掉swap那一行就行
sudo vim /etc/fstab

2.添加k8s的源

curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add
vim /etc/apt/sources.list.d/kubernetes.list
# 将下面的阿里源加入文件中
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main

3.安装 kubelet、kubeadm、kubectl

apt install -y kubelet=1.18.4-00 kubeadm=1.18.4-00 kubectl=1.18.4-00

4.下载镜像

因为 k8s 默认从 k8s.gcr.io 下载需要的镜像,网络是不同的,所以可以把必要的组件,先从registry.cn-hangzhou.aliyuncs.com下载

docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.18.4
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.18.4
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.18.4
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.18.4
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.4.3-0
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.6.7

docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.18.4 k8s.gcr.io/kube-apiserver:v1.18.4
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.18.4 k8s.gcr.io/kube-controller-manager:v1.18.4
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.18.4 k8s.gcr.io/kube-scheduler:v1.18.4
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.18.4 k8s.gcr.io/kube-proxy:v1.18.4
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.2 k8s.gcr.io/pause:3.2
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.4.3-0 k8s.gcr.io/etcd:3.4.3-0
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.6.7 k8s.gcr.io/coredns:1.6.7

5.master初始化

sudo kubeadm init --kubernetes-version=v1.18.4 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12 --v=6
  • --apiserver-advertise-address: k8s 中的主要服务apiserver的部署地址,填自己的管理节点 ip
  • --image-repository: 拉取的 docker 镜像源,因为初始化的时候kubeadm会去拉 k8s 的很多组件来进行部署,所以需要指定国内镜像源,下不然会拉取不到镜像。
  • --pod-network-cidr: 这个是 k8s 采用的节点网络,因为我们将要使用flannel作为 k8s 的网络,所以这里填10.244.0.0/16就好
  • --kubernetes-version: 这个是用来指定你要部署的 k8s 版本的,一般不用填,不过如果初始化过程中出现了因为版本不对导致的安装错误的话,可以用这个参数手动指定。
  • --ignore-preflight-errors: 忽略初始化时遇到的错误,比如说我想忽略 cpu 数量不够 2 核引起的错误,就可以用--ignore-preflight-errors=CpuNum。错误名称在初始化错误时会给出来。

6.master 添加网络组件

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

7.master 创建 token

kubeadm token create --print-join-command

会生成如下信息,在 work 节点执行,这把work加入到集群

kubeadm join 192.168.2.141:6443 --token 17ljby.lk8ckch51yn8eyp8     --discovery-token-ca-cert-hash sha256:66dfd0c4fac7fee3019cfa4c5d5e09a84aa68aeb72f9cf055e836d5f89098345

7.work 节点

kubeadm join 192.168.2.141:6443 --token 17ljby.lk8ckch51yn8eyp8     --discovery-token-ca-cert-hash sha256:66dfd0c4fac7fee3019cfa4c5d5e09a84aa68aeb72f9cf055e836d5f89098345

四、发布应用

1.编写应用

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h5>k8s demo</h5>
</body>
</html>

2.编写dockerfile

dockerfile文件

FROM nginx:alpine

COPY nginx.conf /etc/nginx/nginx.conf

COPY index.html /var/www/demo/index.html

EXPOSE 80

3.构建镜像

docker build -t activepirate/k8s-app-demo:0.1 ./

4.发布镜像

docker push activepirate/k8s-app-demo:0.1

五、部署应用

1.创建 namespace

kubectl create namespace zxm-ns

或者

kubectl apply -f ns.yaml

ns.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: zxm-ns
spec:
  finalizers:
    - kubernetes

2.部署文件

app.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: k8s-demo-deployment
  namespace: zxm-ns
  labels:
    app: k8s-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: k8s-demo
  template:
    metadata:
      labels:
        app: k8s-demo
    spec:
      containers:
        - image: activepirate/k8s-app-demo:0.1
          imagePullPolicy: IfNotPresent
          name: k8s-demo
          ports:
            - containerPort: 80

---

apiVersion: v1
kind: Service
metadata:
  name: k8s-demo-service
  namespace: zxm-ns
spec:
  type: NodePort
  selector:
    app: k8s-demo
  ports:
    - name: web
      protocol: TCP
      port: 88
      targetPort: 80
      nodePort: 30001

3.部署应用

kubectl apply -f app.yaml

4.删除应用

kubectl delete -f app.yaml

六、service 资源

kubernetes 的 service 定义了一种抽象:逻辑上的一组 pod,一种可以访问它们的方式。这一组 pod 能通过 service 被访问到,通过是通过 selector 来实现的。

调用者可以通过 service 进行访问,它不需要知道具体访问的是哪一个节点,具体的策略由 service 来配置,并实现负载均衡。某种意义上也是服务发现和解耦

K8S利用linux的iptables来对数据包的目的地址进行改写来达到转发的目的,而所谓的ServiceIP只是转发记录里的一个虚拟地址

K8S会在集群的每一个节点运行一个叫kube-proxy的Pod,这个Pod负责监听api-server中的Service/EndPoint/Node类型的资源变化事件,然后操作本机的iptables或ipvs来创建ServiceIP,所以K8S集群的节点之外的其它节点是不认识这个ServiceIP的

apiVersion: v1
kind: Service
metadata:
  name: k8s-demo-service
  namespace: zxm-ns
spec:
  type: NodePort      # 配置为NodePort,外部可以访问
  selector:
    app: k8s-demo
  ports:
    - name: web
      protocol: TCP
      port: 30080     # 容器间,服务调用的端口
      targetPort: 80  # 容器暴露的端口,与 Dockerfile 暴露端口保持一致
      nodePort: 30001 # NodePort,外部访问的端口

K8s集群内部节点可以通过 30080 端口访问服务,然而外部网络还是不能够通过 port 访问到服务。

通过 kubectl get services --all-namespaces,可以看到 clusterIP 和 port,以及端口映射 30080:30001/TCP

每个 work 节点容器暴露的端口是 80;master 节点和work 节点暴露的端口是 30001;节点间访问可以通过 clusterIp + 30080 方式访问到服务。

从 port 或者是 nodePort 进入的流量,经过路由转发之后,最终都会都通过 targetPort 进入到 Pod 中。

七、kubectl 命令

kubelet: k8s 的核心服务

kubeadm: 这个是用于快速安装 k8s 的一个集成工具,我们在master1和worker1上的 k8s 部署都将使用它来完成。

kubectl: k8s 的命令行工具,部署完成之后后续的操作都要用它来执行

语法

kubectl [command] [TYPE] [NAME] [flags]
  • command:指定要对一个或多个资源执行的操作,例如 create、get、describe、delete
  • TYPE:指定资源类型,资源类型不区分大小写, 可以指定单数、复数或缩写形式
  • NAME:指定资源的名称。名称区分大小写。 如果省略名称,则显示所有资源的详细信息。例如:kubectl get pods
  • flags:指定可选的参数。例如,可以使用 -s 或 --server 参数指定 Kubernetes API 服务器的地址和端口

1.node

  • 查看 node:kubectl get node

2.namespace

  • 查看 namespace:kubectl get namespaces
  • 创建 namespace: kubectl create namespace ns-name

3.pod

  • 查看 pod:kubectl get pods --all-namespaces
  • 查看 pod的ip:kubectl get pods -o wide --all-namespaces
  • 查看 pod 的 yaml:kubectl get pods <pod_name> -o yaml

4.deployment

  • 查看 deployment:kubectl get deployment --all-namespaces

5.services

服务

services 缩写 svc

  • 查看 services:kubectl get services --all-namespaces

6.replicasets

rs 缩写 replicasets

  • 查看 replicasets:kubectl get rc --all-namespaces

7.daemonsets

守护程序集

daemonsets 缩写 ds

  • 查看 daemonsets:kubectl get ds --all-namespaces

8.apply

apply 命令允许你通过配置文件将配置应用于你的资源。这些配置也可以通过标准输入在命令行输入,但是建议使用文件

9.delete

kubectl delete - 基于文件、标准输入或通过指定标签选择器、名称、资源选择器或资源来删除资源

# 使用 pod.yaml 文件中指定的类型和名称删除 Pod。
kubectl delete -f pod.yaml

# 删除所有带有 '<label-key>=<label-value>' 标签的 Pod 和服务。
kubectl delete pods,services -l <label-key>=<label-value>

# 删除所有 Pod,包括未初始化的 Pod。
kubectl delete pods --all

10.logs

# 返回 Pod <pod-name> 的日志快照。
kubectl logs <pod-name>

# 从 Pod <pod-name> 开始流式传输日志。这类似于 'tail -f' Linux 命令。
kubectl logs --tail=200 -f <pod-name>