- 1、k8s快速入门
- This file controls the state of SELinux on the system.
- SELINUX= can take one of these three values:
- enforcing - SELinux security policy is enforced.
- permissive - SELinux prints warnings instead of enforcing.
- disabled - No SELinux policy is loaded.
- SELINUXTYPE= can take one of three values:
- targeted - Targeted processes are protected,
- minimum - Modification of targeted policy. Only selected processes are protected.
- mls - Multi Level Security protection.
- 3、所有节点安装Docker
- 4、添加阿里云yum源
- 5、安装kubeadm,kubelet 和kubectl
- 6、部署k8s-master
- !/bin/bash
- docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName k8s.gcr.io/$imageName
- 7、加入Kubernetes Node
- 8、入门操作kubernetes集群
- 3、K8s细节
- 4、KubeSphere
1、k8s快速入门
1、简介
1、简介
- Kubernetes 简称k8s。是用于自动部署,扩展和管理容器化应用程序的开源系统。
- 中文官网:https://kubernetes.io/zh/
- 中文社区:https://www.kubernetes.org.cn/
- 官方文档:https://kubernetes.io/zh/docs/home/
社区文档:http://docs.kubernetes.org.cn/
2、部署方式的进化
https://kubernetes.io/zh/docs/concepts/overview/
3、架构
1、整体主从方式
2、Master 节点架构
kube-apiserver
- 对外暴露K8S 的api 接口,是外界进行资源操作的唯一入口
- 提供认证、授权、访问控制、API 注册和发现等机制
- etcd
- etcd 是兼具一致性和高可用性的键值数据库,可以作为保存Kubernetes 所有集群数据的后台数据库。
- Kubernetes 集群的etcd 数据库通常需要有个备份计划
- kube-scheduler
- 主节点上的组件,该组件监视那些新创建的未指定运行节点的Pod,并选择节点让Pod 在上面运行。
- 所有对k8s 的集群操作,都必须经过主节点进行调度
kube-controller-manager
kubelet
- 一个在集群中每个节点上运行的代理。它保证容器都运行在Pod 中。
- 负责维护容器的生命周期,同时也负责Volume(CSI)和网络(CNI)的管理
- kube-proxy
- 负责为Service 提供cluster 内部的服务发现和负载均衡;
- 容器运行环境(Container Runtime)
- 容器运行环境是负责运行容器的软件。
- Kubernetes 支持多个容器运行环境: Docker、containerd、cri-o、rktlet 以及任何实现Kubernetes CRI (容器运行环境接口)。
fluentd
Container:容器,可以是docker 启动的一个容器
- Pod
- k8s 使用Pod 来组织一组容器
- 一个Pod 中的所有容器共享同一网络
- Pod 是k8s 中的最小部署单元
- Volume
- 声明在Pod 容器中可访问的文件目录
- 可以被挂载在Pod 中一个或多个容器指定路径下
- 支持多种后端存储抽象(本地存储,分布式存储,云存储…)
- Controllers:更高层次对象,部署和管理Pod;
- ReplicaSet:确保预期的Pod 副本数量
- Deplotment:无状态应用部署
- StatefulSet:有状态应用部署
- DaemonSet:确保所有Node 都运行一个指定Pod
- Job:一次性任务
- Cronjob:定时任务
- Deployment:
- 定义一组Pod 的副本数目、版本等
- 通过控制器(Controller)维持Pod 数目(自动回复失败的Pod)
- 通过控制器以指定的策略控制版本(滚动升级,回滚等)
- Service
- 定义一组Pod 的访问策略
- Pod 的负载均衡,提供一个或者多个Pod 的稳定访问地址
- 支持多种方式(ClusterIP、NodePort、LoadBalance)
- Label:标签,用于对象资源的查询,筛选
- Namespace:命名空间,逻辑隔离
- 一个集群内部的逻辑隔离机制(鉴权,资源)
- 每个资源都属于一个namespace
- 同一个namespace 所有资源名不能重复
- 不同namespace 可以资源名重复
API:我们通过kubernetes 的API 来操作整个集群。可以通过kubectl、ui、curl 最终发送http+json/yaml 方式的请求给API Server,然后控制k8s集群。k8s 里的所有的资源对象都可以采用yaml 或JSON 格式的文件定义或描述
5、快速体验
1、安装minikube
https://github.com/kubernetes/minikube/releases下载minikube-windows-amd64.exe 改名为minikube.exe打开VirtualBox,打开cmd,运行minikube start —vm-driver=virtualbox —registry-mirror=https://registry.docker-cn.com等待20 分钟左右即可
6、流程叙述
(1)通过Kubectl 提交一个创建RC(Replication Controller)的请求,该请求通过APIServer被写入etcd 中
- (2)此时Controller Manager 通过API Server 的监听资源变化的接口监听到此RC 事件
- (3)分析之后,发现当前集群中还没有它所对应的Pod 实例
- (4)于是根据RC 里的Pod 模板定义生成一个Pod 对象,通过APIServer 写入etcd
- (5)此事件被Scheduler 发现,它立即执行一个复杂的调度流程,为这个新Pod 选定一个落户的Node,然后通过API Server 讲这一结果写入到etcd 中,
- (6)目标Node 上运行的Kubelet 进程通过APIServer 监测到这个“新生的”Pod,并按照它的定义,启动该Pod 并任劳任怨地负责它的下半生,直到Pod 的生命结束。
- (7)随后,我们通过Kubectl 提交一个新的映射到该Pod 的Service 的创建请求
- (8)ControllerManager 通过Label 标签查询到关联的Pod 实例,然后生成Service 的Endpoints 信息,并通过APIServer 写入到etcd 中,
- (9)接下来,所有Node 上运行的Proxy 进程通过APIServer 查询并监听Service 对象与其对应的Endpoints 信息,建立一个软件方式的负载均衡器来实现Service 访问到后端Pod 的流量转发功能。
- k8s 里的所有的资源对象都可以采用yaml 或JSON 格式的文件定义或描述
2、搭建
1、搭建相关文件下载
- 文件下载 k8s环境搭建的相关文件
- 链接: https://pan.baidu.com/s/1iIIlxMRuKw7CcX8DNPsosQ 提取码: 8urk
-
2、配置3台虚拟机环境
1、查看虚拟机的主网卡
在virtaulbox中查看自己的网卡
- 查看到我这边是192.168.33.1
- 如果不存在就创建一个
2、创建Vagrantfile文件批量创建虚拟机
- 使用vagrant创建3个虚拟机节点
在合适的目录中创建一个Vagrantfile文件,
修改当前虚拟机合适的网卡,我这里是192.168.33.1,所以从192.168.33.99开始网上
Vagrant.configure("2") do |config|
(1..3).each do |i|
config.vm.define "k8s-node#{i}" do |node|
# 设置虚拟机的Box
node.vm.box = "centos/7"
# 设置虚拟机的主机名
node.vm.hostname="k8s-node#{i}"
# 设置虚拟机的IP
node.vm.network "private_network", ip: "192.168.33.#{99+i}", netmask: "255.255.255.0"
# 设置主机与虚拟机的共享目录
# node.vm.synced_folder "~/Documents/vagrant/share", "/home/vagrant/share"
# VirtaulBox相关配置
node.vm.provider "virtualbox" do |v|
# 设置虚拟机的名称
v.name = "k8s-node#{i}"
# 设置虚拟机的内存大小
v.memory = 2048
# 设置虚拟机的CPU个数
v.cpus = 4
end
end
end
end
3、进入刚创建的Vagrantfile文件目录
使用命令来启动虚拟机
vagrant up
过一会就可以看到三台机器启动了
4、连接虚拟机
使用
vagrant ssh k8s-node1
5、修改为可远程访问
登录之后修改这个文件
sudo vi /etc/ssh/sshd_config
PasswordAuthentication 设置为yes
PasswordAuthentication yes
修改完之后重启一下服务sshd
service sshd restart
6、使用FinalShell连接三台虚拟机
7、配置网络环境
使用命令 ```shell [root@k8s-node1 ~]# ip route default via 10.0.2.2 dev eth0 proto dhcp metric 101 10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15 metric 101 192.168.33.0/24 dev eth1 proto kernel scope link src 192.168.33.100 metric 100
- 再用如下命令查看
```shell
[root@k8s-node1 ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:4d:77:d3 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global noprefixroute dynamic eth0
valid_lft 83356sec preferred_lft 83356sec
inet6 fe80::5054:ff:fe4d:77d3/64 scope link
valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:2c:44:28 brd ff:ff:ff:ff:ff:ff
inet 192.168.33.100/24 brd 192.168.33.255 scope global noprefixroute eth1
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe2c:4428/64 scope link
valid_lft forever preferred_lft forever
- 发现eth0的网络ip都是一样的10.0.2.15,
- 所以我们来修改网络使用virtualbox中的NAT来启动网络
(1)关闭3台虚拟机
(2)全局设定中创建一个nat网络
(3)为每台虚拟机修改地址
- 默认第一个网卡是网络地址转换
- 修改为刚刚创建的NAT网络
- 并且刷新一下MAC地址
- 因为不刷新的话会导致刚刚的mac地址都一样
- 记住这样配置之后就不要再使用vagrant命令来启动了,容易导致网络设置被初始化
- 接着重新启动
- 重新使用命令查看之后发现eth0的ip都不一样了
- 分别k8s-node1:10.0.2.15
- 分别k8s-node2:10.0.2.4
- 分别k8s-node3:10.0.2.5
在三个虚拟机中第一个网卡是以后k8s中默认要用的网卡,相互之间可以ping通
8、关闭防火墙,就不再设置各种进出限制了
systemctl stop firewalld systemctl disable firewalld
9、关闭安全策略
默认策略
- 为enforcing ```shell [root@k8s-node3 ~]# cat /etc/selinux/config
This file controls the state of SELinux on the system.
SELINUX= can take one of these three values:
enforcing - SELinux security policy is enforced.
permissive - SELinux prints warnings instead of enforcing.
disabled - No SELinux policy is loaded.
SELINUX=enforcing
SELINUXTYPE= can take one of three values:
targeted - Targeted processes are protected,
minimum - Modification of targeted policy. Only selected processes are protected.
mls - Multi Level Security protection.
SELINUXTYPE=targeted
- 关闭selinux
```shell
sed -i 's/enforcing/disabled/' /etc/selinux/config
全局禁用
setenforce 0
10、关闭内存交换
关闭swap:
swapoff -a 临时 sed -ri 's/.*swap.*/#&/' /etc/fstab 永久 free -g 验证,swap 必须为0;
11、添加主机名与IP 对应关系
hostnamectl set-hostname
:指定新的hostname su 切换过来
vi /etc/hosts
添加
10.0.2.15 k8s-node1 10.0.2.4 k8s-node2 10.0.2.5 k8s-node3
12、将桥接的IPv4 流量传递到iptables 的链:
如果不做可能会导致流量指标的消失
cat > /etc/sysctl.d/k8s.conf << EOF net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF sysctl --system
13、疑难问题:
遇见提示是只读的文件系统,运行如下命令
mount -o remount rw /
14、date 查看时间(可选
yum install -y ntpdate ntpdate time.windows.com 同步最新时间
3、所有节点安装Docker
1、卸载系统之前的docker
sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
2、安装Docker-CE
安装必须的依赖
sudo yum install -y yum-utils \ device-mapper-persistent-data \ lvm2
设置docker repo 的yum 位置
sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
安装docker,以及docker-cli
sudo yum install -y docker-ce docker-ce-cli containerd.io
3、配置docker加速
sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://6i77dtkl.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker
4、启动docker& 设置docker开机自启动
设置完这个三个环境可以备份一下
systemctl enable docker
4、添加阿里云yum源
cat > /etc/yum.repos.d/kubernetes.repo << EOF [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=0 repo_gpgcheck=0 gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF
5、安装kubeadm,kubelet 和kubectl
yum list|grep kube yum install -y kubelet-1.17.3 kubeadm-1.17.3 kubectl-1.17.3 systemctl enable kubelet systemctl start kubelet
检查版本
kubectl version
6、部署k8s-master
1、master 节点初始化
以下命令只在k8s-node1虚拟机创建
- 由于默认拉取镜像地址k8s.gcr.io 国内无法访问,这里指定阿里云镜像仓库地址。可以手动按照我们的images.sh 先拉取镜像,地址变为registry.aliyuncs.com/google_containers 也可以。
images=( kube-apiserver:v1.17.3 kube-proxy:v1.17.3 kube-controller-manager:v1.17.3 kube-scheduler:v1.17.3 coredns:1.6.5 etcd:3.4.3-0 pause:3.1 )
for imageName in ${images[@]} ; do docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName k8s.gcr.io/$imageName
done
- 执行命令下载
```shell
./master_images.sh
科普:无类别域间路由(Classless Inter-Domain Routing、CIDR)是一个用于给用户分配IP地址以及在互联网上有效地路由IP 数据包的对IP 地址进行归类的方法。拉取可能失败,需要下载镜像。运行完成提前复制:加入集群的令牌
kubeadm init \ --apiserver-advertise-address=10.0.2.15 \ --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \ --kubernetes-version v1.17.3 \ --service-cidr=10.96.0.0/16 \ --pod-network-cidr=10.244.0.0/16
执行上面命令之后会打印出其他节点加入的命令
kubeadm join 10.0.2.15:6443 --token k35xgr.g8e30qz3jmzm8d3e \ --discovery-token-ca-cert-hash sha256:16b02004daeff5717f1ca6ae82e8c88e822c2b3ddaff00711a4087f51f6920b0
2、测试kubectl(主节点执行)
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
3、获取所有节点
目前master 状态为notready。等待网络加入完成即可。
kubectl get nodes
查看kubelet 日志
journalctl -u kubelet
-
4、安装Pod 网络插件(CNI)
kubectl apply -f \ https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
以上地址可能被墙,大家获取上传我们下载好的flannel.yml 运行即可,同时flannel.yml 中指定的images 访问不到可以去docker hub 找一个wget yml 的地址
- vi 修改yml 所有amd64 的地址都修改了即可。
- 等待大约3 分钟
查看指定名称空间的pods
kubectl get pods -n kube-system
查看所有名称空间的pods
kubectl get pods –all-namespace
如果网络出现问题,关闭cni0,重启虚拟机继续测试
ip link set cni0 down
监控pod 进度
在Node 节点执行。向集群添加新节点,执行在kubeadm init 输出的kubeadm join 命令:
- 以下的tonke有效期大概是2小时
- 确保node 节点成功
kubeadm join 10.0.2.15:6443 --token k35xgr.g8e30qz3jmzm8d3e \ --discovery-token-ca-cert-hash sha256:16b02004daeff5717f1ca6ae82e8c88e822c2b3ddaff00711a4087f51f6920b0
token 过期怎么办
- 设置永久的
kubeadm token create --print-join-command kubeadm token create --ttl 0 --print-join-command
- 设置永久的
监控pod 进度
获取到tomcat 信息
kubectl get pods -o wide
获取pod列表
kubectl get pods
2、暴露nginx 访问
Pod 的80 映射容器的8080;service 会代理Pod 的80
kubectl expose deployment tomcat6 --port=80 --target-port=8080 --type=NodePort
获取服务信息
- 可以看到暴露出来了端口32012,以下三个方式都可以访问了
- http://192.168.33.100:32012/
- http://192.168.33.101:32012/
- http://192.168.33.102:32012/
```shell
[root@k8s-node1 k8s]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1
443/TCP 90m tomcat6 NodePort 10.96.142.33 80:32012/TCP 20s
- 可以看到暴露出来了端口32012,以下三个方式都可以访问了
<a name="gRVgV"></a>
#### 3、动态扩容测试
- 获取所有部署
```shell
kubectl get deployment
应用升级 (—help 查看帮助)
kubectl set image
扩容或者缩放直接设置就行
kubectl scale --replicas=3 deployment tomcat6
4、删除
先查看当前k8s的信息
kubectl get all
使用删除命令
kubectl delete 上面的name的输入例如 kubectl delete deployment.apps/tomcat6 kubectl delete service/tomcat6
3、K8s细节
1、kubectl
1、文档
https://kubernetes.io/zh/docs/reference/kubectl/overview/
2、资源类型
https://kubernetes.io/zh/docs/reference/kubectl/overview/#%E8%B5%84%E6%BA%90%E7%B1%BB%E5%9E%8B
3、格式化输出
https://kubernetes.io/zh/docs/reference/kubectl/overview/#%E6%A0%BC%E5%BC%8F%E5%8C%96%E8%BE%93%E5%87%BA
4、常用操作
https://kubernetes.io/zh/docs/reference/kubectl/overview/#%E7%A4%BA%E4%BE%8B-%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C
5、命令参考
https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands
2、yaml 语法
1、yml 模板
2、使用yaml部署之前的tomcat6
删除之前的tomcat6
kubectl get all kubectl delete deployment.apps/tomcat6 kubectl delete service/tomcat6
用之前的创建tomcat6的命令来导出yaml
kubectl create deployment tomcat6 --image=tomcat:6.0.53-jre8 \ --dry-run -o yaml > tomcat6-deployment.yaml
生成晚间tomcat6-deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: tomcat6 name: tomcat6 spec: replicas: 1 selector: matchLabels: app: tomcat6 strategy: {} template: metadata: creationTimestamp: null labels: app: tomcat6 spec: containers: - image: tomcat:6.0.53-jre8 name: tomcat resources: {} status: {}
再让tomcat6的服务暴露也生成出yaml
kubectl expose deployment tomcat6 --port=80 --target-port=8080 --type=NodePort \ --dry-run -o yaml
生成
apiVersion: v1 kind: Service metadata: creationTimestamp: null labels: app: tomcat6 name: tomcat6 spec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: tomcat6 type: NodePort status: loadBalancer: {}
修改上面的两个yaml合成为一个总的yaml
- 部署三份,并且删除多余的
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: tomcat6
name: tomcat6
spec:
replicas: 3
selector:
matchLabels:
app: tomcat6
template:
metadata:
labels:
app: tomcat6
spec:
containers:
- image: tomcat:6.0.53-jre8 name: tomcat
- 部署三份,并且删除多余的
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: tomcat6
name: tomcat6
spec:
replicas: 3
selector:
matchLabels:
app: tomcat6
template:
metadata:
labels:
app: tomcat6
spec:
containers:
apiVersion: v1 kind: Service metadata: labels: app: tomcat6 name: tomcat6 spec: ports:
- port: 80 protocol: TCP targetPort: 8080 selector: app: tomcat6 type: NodePort ```
- 部署
```shell [root@k8s-node1 ~]# kubectl get all NAME READY STATUS RESTARTS AGE pod/tomcat6-5f7ccf4cb9-k99db 1/1 Running 0 20s pod/tomcat6-5f7ccf4cb9-ld2bk 1/1 Running 0 20s pod/tomcat6-5f7ccf4cb9-wfgbw 1/1 Running 0 20skubectl apply -f tomcat6-deployment.yaml
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1
NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/tomcat6 3/3 3 3 20s
NAME DESIRED CURRENT READY AGE replicaset.apps/tomcat6-5f7ccf4cb9 3 3 3 20s
- 访问[http://192.168.33.100:31647/](http://192.168.33.100:31647/)就可以直接访问了
<a name="EYHRk"></a>
### 4、ingress
<a name="tZWPk"></a>
#### 1、简介
- 通过Service 发现Pod 进行关联。基于域名访问。
- 通过Ingress Controller 实现Pod 负载均衡
- 支持TCP/UDP 4 层负载均衡和HTTP 7 层负载均衡

<a name="nil6J"></a>
#### 2、部署
先查看是否有ingress 相关配置
```shell
kubectl get pods --all-namespaces
- 查看发现只有defaut和kube-system相关的tasrs
- 使用我们上面上传的网盘的k8s中的ingress-controller.yaml
直接部署这个
kubectl apply -f ingress-controller.yaml
再次查看pod信息会发现多了一个ingress-nginx
我们就可以来为我们的tomcat来创建一个ingress规则
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: web spec: rules: - host: http: paths: - backend: serviceName: tomcat6 servicePort: 80
配置完之后我们还需要在宿主机的hosts配置上
默认的dashboard 没啥用,我们用kubesphere 可以打通全部的devops 链路。
- Kubesphere 集成了很多套件,集群要求较高
Kuboard 也很不错,集群要求不高
- https://kuboard.cn/support/
1、简介
KubeSphere 是一款面向云原生设计的开源项目,在目前主流容器调度平台Kubernetes 之
上构建的分布式多租户容器管理平台,提供简单易用的操作界面以及向导式操作方式,在降
低用户使用容器调度平台学习成本的同时,极大降低开发、测试、运维的日常工作的复杂度2、安装
1、前提条件
https://v2-1.docs.kubesphere.io/docs/zh-CN/installation/prerequisites/2、安装前提环境
1、安装helm(master 节点执行)
Helm 是Kubernetes 的包管理器。包管理器类似于我们在Ubuntu 中使用的apt、Centos
中使用的yum 或者Python 中的pip 一样,能快速查找、下载和安装软件包。Helm 由客
户端组件helm 和服务端组件Tiller 组成, 能够将一组K8S 资源打包统一管理, 是查找、共
享和使用为Kubernetes 构建的软件的最佳方式。
(1)、安装curl -L https://git.io/get_helm.sh | bash
- https://kuboard.cn/support/
有可能下载不了,墙的原因,上传我们给定的get_helm.sh,chmod 700 然后./get_helm.sh
chmod 700 get_helm.sh
可能有文件格式兼容性问题,用vi 打开该sh 文件,输入: