k8s概念

架构

Kubernetes是一个完备的分布式系统支撑平台。Kubernetes具有完备的集群管理能力,包括多层次的安全防护和准入机制/多租户应用支撑能力、透明的服务注册和服务发现机制、内建智能负载均衡器、强大的故障发现和自我修复功能、服务滚动升级和在线扩容能力、可扩展的资源自动调度机制,以及多粒度的资源配额管理能力。同时kubernetes提供了完善的管理工具,这些工具覆盖了包括开发、测试部署、运维监控在内的各个环节;因此kubernetes是一个全新的基于容器技术的分布式架构解决方案,并且是一个一站式的完备的分布式系统开发和支撑平台

Kubernetes简易.png
Kubernetes简易.png

Kubernetes Service

Service的服务进程目前都基于Socker通信方式对外提供服务,比如redis、memcache、MySQL、Web Server,或者是实现了某个具体业务的一个特定的TCP Server进程。虽然一个Service通常由多个相关的服务进程来提供服务,每个服务进程都有一个独立的Endpoint(IP+Port)访问点,但Kubernetes 能够让我们通过Service虚拟Cluster IP+Service Port连接到指定的Service上。有了Kubernetes内建的透明负载均衡和故障恢复机制,不管后端有多少服务进程,也不管某个服务进程是否会由于发生故障而重新部署到其他机器,都不会影响到我们对服务的正常调用。更重要的是这个Service本身一旦创建就不再变化,这意味着Kubernetes集群中,我们再也不用为了服务的IP地址变来变去的问题而头疼。

service可以通过访问点去访问不同的子节点下面的Pod上,类似一个Proxy的概念,个人理解为他本身类似集群,通过service分发
swarm集群中的service类似,可以保持容器启动数量,由于权限相关问题,用户手动命令要大于service控制的权限级别,因此如果在使用service控制Pod时,有可能导致报错,不推荐使用

Kubernetes Service.png
Kubernetes Service.png

Kubernetes Pod

Pod运行在一个我们称之为节点Node的环境中,可以是私有云也可以是公有云的虚拟机或者物理机,通常在一个节点上运行几百个Pod;其次,每个Pod里运行着一个特殊的被称之为Pause的容器,其他容器则为业务容器,这些业务容器共享Pause容器的网络栈和Volume挂载卷,因此他们之间的通讯和数据交换更为高效。在设计时我们可以充分利用这一特征将一组密切相关的服务进程放入同一个Pod中。
并不是每个Pod和它里面运行的容器都能映射到一个Service 上,只有那些提供服务(无论是对内还是对外)的一组Pod才会被映射成一个服务。

Kubernetes Pod.png
Kubernetes Pod.png

Pod & Container

  • 容器(Container)是一种高度隔离的封装程序

    容器1.png
    容器1.png

    非所有的应用都适合选择容器,开发者可以根据自己应用的特点和需求选择最适合的计算单元。例如,你的应用是高性能、互信的,且处于同一个管理区域,那么用线程或者进程就可以满足;但如果你的应用是多租户的,并且和其他应用运行在同一个空间,那么你就需要考虑如何将这些应用安全地隔离开,使得数据不会被泄露或性能受到影响。那么这时,容器也许就是一个不错的选择了。
    容器便于管理,因为现在市场上有着完全完善的生态以及Docker的支持度愈发增加,越来越多的公司(个人)选择Docker,我个人也更倾向于Docker,有了Docker就可以非常完美的管理Images以及Container

    容器2.png
    容器2.png

    容器是只占用很少的空间的,真正占用空间大的是Images,也可以说 Container 依赖 Images

  • Pod,一种增强型容器
    Pod是一种组合的多容器运行单元,也是Kubernetes里的一个基础单元。你可以把它看作是一种容器的扩展或者增强型的容器。Pod里面包括一个主容器和数个辅助容器,它们共同完成一个特定的功能。把多个进程(容器也是一种隔离的进程)打包在一个Name Space里的时候,就构成了一个Pod。Pod里面不同进程的应用包装仍然是独立的(每个容器都会有自己的镜像)。
    Pod的意义在于,它可以既保持主容器和辅助容器的的密切关系,又保持主容器的独立性。由于主容器和辅助容器的生命周期相同,可以同时被创建和销毁,因此把它们放在一个Pod中,可以使他们的交互更加高效。

参考文档

Aholiab - 云原生的基石,一文读懂容器、Docker、Pod到底是什么!
abcdocker编写k8s中文文档
Ubuntu18.04使用kubeadm部署v1.18 HA集群

部署k8s

机器选择

这里我只做学习用途,因此开通的是阿里的按量计费机器以及低配置机器

  • master01 2H8G 阿里云 Ubuntu18.04
  • node01 2H8G 阿里云 Ubuntu18.04

部署环境

Ubuntu修改仓库镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sudo cat > /etc/apt/sources.list << EOF
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse

deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
EOF

关闭防火墙

1
sudo ufw disable

时间同步

1
2
3
4
5
6
7
8
sudo apt-get install chrony -y && sudo systemctl start chrony && sudo systemctl enable chrony

#查看chrony连接的公网服务器
cat /etc/chrony/chrony.conf
pool ntp.ubuntu.com iburst maxsources 4
pool 0.ubuntu.pool.ntp.org iburst maxsources 1
pool 1.ubuntu.pool.ntp.org iburst maxsources 1
pool 2.ubuntu.pool.ntp.org iburst maxsources 2

禁用swap

1
sudo swapoff -a

上述命令可以临时禁用掉swap,如果想要永久禁止,需要编辑 /etc/fstab 文件,将swap那一行注释掉,如果没有则不管

禁用SELinux
如果安装了则需要禁止掉,如果没有安装则可以跳过此步骤

1
2
3
sudo setenforce 0           #临时关闭
sudo vi /etc/selinux/config #永久关闭
SELINUX=permissive

修改内核

1
2
3
4
5
6
sudo  cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1 #开启ipv4转发,允许内置路由
EOF
sudo sysctl --system

修改时区

1
2
sudo ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
sudo bash -c "echo 'Asia/Shanghai' > /etc/timezone"

安装Docker
Step 1: 安装必要的一些系统工具

1
2
sudo apt-get update
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common

Step 2: 安装GPG证书

1
sudo curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

Step 3: 写入软件源信息

1
sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"

Step 4: 查找Docker-CE的版本

1
sudo apt-cache madison docker-ce

Step 5: 安装指定版本的Docker-CE,docker-ce=VERSION

1
sudo apt-get -y install docker-ce

Setp 6: 安装完成后Docker默认就已经启动和加入开机自启了,这点我们不需要再做了,不过可以检查一下

1
2
sudo systemctl status docker
sudo systemctl is-enabled docker

Setp 7: 配置Docker镜像加速以及指定cgroup驱动为systemd

1
2
3
4
5
6
7
8
9
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"exec-opts": ["native.cgroupdriver=systemd"],
"registry-mirrors": ["https://81z69sad.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

Setp 8: 配置完成后使用 docker info 可以看到修改的配置信息

配置主机名

1
2
3
4
cat >> /etc/hosts << EOF
172.26.147.37 master01
172.26.147.36 node01
EOF

安装Kubeadm Kubelet Kubectl
Step 1: 安装必要的程序包

1
apt-get update && apt-get install -y apt-transport-https

Step 2: 导入Kubernetes官方包签名密钥

1
sudo curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -

Step 3: 添加Kubernetes仓库

1
2
3
cat > /etc/apt/sources.list.d/kubernetes.list << EOF
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF

Step 4: 更新仓库

1
apt-get update

Step 5: 查找kubeadm kubelet kubectl版本

1
2
3
apt-cache madison kubeadm | grep 1.18
apt-cache madison kubelet | grep 1.18
apt-cache madison kubectl | grep 1.18

目前1.18发布了1.18.0-00 1.18.1-00 1.18.2-00 三个版本

Step 6: 指定版本安装kubelet kubeadm kubectl(如果安装最新版本则无需带版本号)

1
apt-get install kubeadm kubelet kubectl -y

Master节点部署

根据需要修改的参数更换以下内容

1
2
3
4
5
6
7
8
9
kubeadm init \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.18.0 \
--control-plane-endpoint master01 \
--pod-network-cidr=10.244.0.0/16 \
--service-cidr=10.96.0.0/12 \
--apiserver-advertise-address=0.0.0.0 \
--ignore-preflight-errors=Swap \
--token-ttl 30m

参数说明

  • image-repository:初始化过程中会去docker仓库拉去镜像,默认指定的为docker hub(国内访问网速不堪),所以在此使用–image-repository参数指定阿里云镜像。
  • kubernetes-version:指定正在使用的 Kubernetes 程序组件的版本号,需要与 kubelet kubeadm kubectl 的版本号一致。
  • control-plane-endpoint: 指定控制平面的固定访问端点,可以是IP地址或DNS名称,会被用于集群管理员及集群组件的kubeconfig配置文件API Server的访问地址;单控制平面部署时可以不使用该选项(如果是单个Master部署则不需要使用该选项,因为等会我们要再加入其它两个Master节点到控制平面,所以这里加上此参数)。
  • pod-network-cidr:Pod 网络的地址范围,其值为 CIDR 格式的网络地址,使用 flannel 网络插件时,其默认地址为 10.244.0.0/16。
  • service-cidr:Service 的网络地址范围,其值为 CIDR 格式的网络地址,默认地址为 10.96.0.0/12。
  • apiserver-advertise-address:API Server 通告给其它组件的IP地址,一般为 Master 节点的IP地址,0.0.0.0 标识节点上所有可用的地址。
    ignore-preflight-errors:忽略哪些运行时的错误信息,其值为 Swap 时,表示忽略因 swap 未关闭而导致的错误。
  • token-ttl:token令牌自动删除时间,默认为24小时,指定为 0 表示永不过期,指定单位可以使 秒s 分m 时h,在node加入Kubernetes集群时需要指定token。
    初始化过程
    01.png
    01.png
    02.png
    02.png
    03.png
    03.png
    初始化完成
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    #您的Kubernetes控制平面初始化成功!
    Your Kubernetes control-plane has initialized successfully!

    #要开始使用您的集群,您需要作为一个普通用户运行以下程序:
    To start using your cluster, you need to run the following as a regular user:
    mkdir -p $HOME/.kube
    sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    sudo chown $(id -u):$(id -g) $HOME/.kube/config

    #你需要部署一个网络插件到集群中才能够使Kubernetes网络运转起来
    You 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/

    #如果要添加其它控制平面到集群中使用以下命令
    You can now join any number of control-plane nodes by copying certificate authorities
    and service account keys on each node and then running the following as root:
    kubeadm join k8s-devops.io:6443 --token 8r7sjk.9a31rmcjot9650fe \
    --discovery-token-ca-cert-hash sha256: \
    --control-plane

    #如果要添加数据平面节点到集群中使用以下命令
    Then you can join any number of worker nodes by running the following on each as root:
    kubeadm join k8s-devops.io:6443 --token 8r7sjk.9a31rmcjot9650fe \
    --discovery-token-ca-cert-hash sha256:

创建用户

1
2
3
4
5
root@master01:~# useradd -m -s /bin/bash k8s  # 创建用户
root@master01:~# passwd k8s # 设置密码
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully

为普通用户提权

1
root@master01:~# echo 'k8s ALL=(ALL:ALL) NOPASSWD:ALL' >> /etc/sudoers.d/k8s

创建权限

1
2
3
4
5
6
root@master01:~# su k8s  # 切换用户
k8s@master01:/root$
k8s@master01:/root$ cd / # 切换目录
k8s@master01:/$ mkdir -p $HOME/.kube #在当前用户家目录下创建.kube目录
k8s@master01:/$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config #复制config命令配置文件到当前用户.kube目录下
k8s@master01:/$ sudo chown $(id -u):$(id -g) $HOME/.kube/config #修改config文件权限

部署网络插件
Step 1: 可以直接在线部署(如果网络下载不了的情况下,也可以先试用浏览器下载后上传到服务器上)

1
k8s@master01:/$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

Step 2: 如果上述方法还是不行,则可以尝试使用我的

1
kubectl apply -f https://api.0161.org/resources/kube-flannel.yml

Step 3: 上传完后修改文件的属性信息(如上述1,2步骤已完成则直接跳过)

1
k8s@master01:/$ sudo chown -Rf k8s.k8s kube-flannel.yml

Step 4: 然后指定文件部署网络插件(如上述1,2步骤已完成则直接跳过)

1
2
3
4
5
6
7
8
9
10
11
k8s@master01:/$ kubectl apply -f kube-flannel.yml
podsecuritypolicy.policy/psp.flannel.unprivileged created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds-amd64 created
daemonset.apps/kube-flannel-ds-arm64 created
daemonset.apps/kube-flannel-ds-arm created
daemonset.apps/kube-flannel-ds-ppc64le created
daemonset.apps/kube-flannel-ds-s390x created

Step 5: 查看网络插件是否部署完成(下面有一个叫kube-flannel-ds-amd64的Pod)
如果发现你的 flannel Pod 处于 ImagePullBackOff 状态,那么就是 flannel 镜像未拉取成功,而正常的则为 Running状态

1
2
k8s@master01:/$ kubectl get pods -n kube-system | grep flannel
kube-flannel-ds-amd64-hx9cr 1/1 Running 0 2m3s

Step 6: 查看目前k8s节点信息

1
2
3
k8s@master01:/$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
master01 Ready master 65m v1.18.6

子节点加入到集群

master节点查看join参数

1
kubeadm token create --print-join-command

子节点运行

1
kubeadm join master01:6443 --token 8z8ot9.ylyj39j1po0hgyun     --discovery-token-ca-cert-hash sha256:e0bb3c41**********************************813c84472f65c

04.png
04.png

安装Dashboard

官方文档方式启动(不建议)

与端口+ip只能选择一种使用!!!

1
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.3/aio/deploy/recommended.yaml

如遇到无法访问或者网络连接问题可以使用我的备份文件

1
kubectl apply -f https://api.0161.org/resources/recommended.yaml

代理方式启动

1
kubectl proxy

05.png
05.png

端口+IP启动(推荐)

环境部署
下载文件

1
wget https://k8s-1252147235.cos.ap-chengdu.myqcloud.com/dashboard/dashboard.yaml

拉取镜像

1
sudo docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kubernetes-dashboard-amd64:v1.10.1

创建服务

1
sudo kubectl apply -f dashboard.yaml

浏览器输入 https://IP:30001 打开 (可以使用Safari或者火狐,Chrome无法访问)

06.png
06.png

绑定用户
1
2
sudo kubectl create serviceaccount dashboard-admin -n kube-system
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard

获取Token

1
kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')

按Token启动

07.png
07.png

赋予用户权限

单命名空间权限文件及绑定
创建 role.yaml

1
2
3
4
5
6
7
8
9
10
11
12
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: kube-system
name: role-dashboard-admin
rules:
- apiGroups: [""]
resources: ["pods","services"]
verbs: ["get", "watch", "list"]
- apiGroups: ["extensions", "apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

创建 role-bind.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: role-bind-dashboard-admin
namespace: kube-system
subjects:
- kind: ServiceAccount
name: dashboard-admin
namespace: kube-system
roleRef:
kind: Role
name: role-dashboard-admin
apiGroup: rbac.authorization.k8s.io

集群权限配置及绑定
创建 cluster-role.yaml

1
2
3
4
5
6
7
8
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: cluster-role-dashboard-admin
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]

创建 cluster-role-bind.yaml

1
2
3
4
5
6
7
8
9
10
11
12
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: cluster-role-bind-dashboard-admin
subjects:
- kind: ServiceAccount
name: dashboard-admin
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-role-dashboard-admin
apiGroup: rbac.authorization.k8s.io

执行命令

1
2
3
4
kubectl create -f role.yaml
kubectl create -f role-bind.yaml
kubectl create -f cluster-role.yaml
kubectl create -f cluster-role-bind.yaml

完成权限配置,可根据自身情况增加配置!

常用k8s命令

  • 查看pod列表

    1
    2
    kubectl get pods --all-namespaces   # 查看所有
    sudo kubectl get pod -n kube-system # 查看指定命名空间
  • 查看service列表

    1
    kubectl get service --all-namespaces   # 查看所有
  • 删除指定命名空间下的service

    1
    kubectl delete service serviceName --namespace=namespaceName
  • 删除指定命名空间下的pod

    1
    kubectl delete pod podName --namespace=namespaceName
  • 查看所有deployment

    1
    kubectl get deployment -A
  • 删除指定deployment

    1
    kubectl delete deployment podName
  • 查看指定命名空间端口

    1
    sudo kubectl get pod,svc -n kube-system