--------------------------------------------
容器介绍
--------------------------------------------
# 导入导出镜像
docker save xxx > xx.tar
docker load -i xx.tar
docker save 可导出多个镜像

# 查看镜像
docker imges

# 删除镜像
docker rmi xxx

# 查看容器运行状态
docker ps -a

# 运行容器
docker run -dit --name=xxx 容器名

# 查看容器信息
docker inspect xxx 

# 容器一旦创建好了映射端口,没办法再次修改,只能删除容器重建
docker -dit --name=xxx -p 3307:3306
冒号后面是容器内部端口,冒号前面是宿主机端口

# 容器的常见命令
docker exec 
docker start
docker stop
docker restart 
docker logs -f node #约等于tail -f
docker inspect

# 宿主机文件拷贝到容器中
docker cp xxx 容器名:目录

# 数据卷
docker run -dit --name xxx -v /宿主机目录:/容器目录 xxx

# 简化
docker run -dit --name=blog -p 80:80 -v /web:/var/www/html --link db:mysql -e WORDPRESS_DB_HOST=mysql -e WORDPRESS_DB_USER=root -e WORDPRESS_DB_PASSWORD=redhat -e WORDPRESS_DB_NAME=wordpress wordpress
docker run -dit --name=blog -p 80:80 -v /web:/var/www/html --link db:mysql wordpress

# 容器网络
docker network inspect bridge
docker network create -d bridge --subnet=10.0.0.0/24 br0
man -k docker

# 自定义镜像
dockfile

```
FROM centos # 指明基镜像
MAINTAINER xxx # 镜像作者

# 以下命令会在临时容器中执行,再重新生成新的镜像
RUN yum install net-tools -y
ADD /xxx/xxx /xxx/xxx # 拷贝到容器内部路径
CMD ["/bin/bash"]
```

# ADD 拷贝后的文件会自动解压
# COPY 没有自动解压
docker build -t centos:v1 ./ -f dockerfile文件名

```
FROM centos # 指明基镜像
MAINTAINER xxx # 镜像作者

ENV aa=123
VOLUME ["/data"]

CMD ["/bin/bash"]
```

# ENV 指定环境变量
# USER 指定用户
# VOLUME 指定文件路径

# 搭建本地仓库
# harbor registry
# docker 1.9.3开始是以https上传,需要做证书
/etc/docker/daemon.json加入
"insecure-registries":[xxx.xxx.xxx.xxx:5000]

# 拉取镜像添加默认路径
vim /etc/sysconfig/docker
ADD_REGISTRY="--add-registry"

# 查看仓库里的镜像
curl -s xxx.xxx.xxx.xxx:5000/v2/_catalog | json_reformat
curl -s xxx.xxx.xxx.xxx:5000/v2/tags/list

# 删除仓库里的镜像
使用第三方脚本:delete_docker_registry_image
export REGISTRY_DATA_DIR=/xxx/docker/registry/v2

delete_docker_registry_image -i 镜像名

# 限制容器资源
docker run -dit -m(限制内存大小)

docker run -dit --cpuset-cpu=0 # 指定在0号CPU上

ps mo pid, comm, psr $(pgrep ssh)

# compose 容器的编排工具
compose
swarm
mesos
kubernetes

docker-compose start # 开启容器
docker-compose stop # 停止容器
docker-compose ps # 查看容器状态
docker-compose rm # 删除容器
docker-compose up -d # 后台加载ocker-compose.yaml,生成容器
# 主要依赖于docker-compose.yaml


# harbor
上传镜像前:
1.需要该项目的用户权限分配到位
2.修改需要上传的镜像tag
3.docker login xxx.xxx.xxx.xxx
4.dokcer push xxx

--------------------------------------------
k8s
--------------------------------------------
# 安装k8s、kubeadm
各组件作用,所有组件都是以容器方式运行
scheduler  调度组件
etcd       分布式数据库
svc-ip     负载IP
kubeproxy  负载代理
kubelt     接收kubectl发送的请求

更新yum源
设置hosts

# 参考文档
https://baijiahao.baidu.com/s?id=1711041019758002121&wfr=spider&for=pc

#cent OS 7镜像
https://vault.centos.org/7.4.1708/isos/x86_64/

安装k8s,关闭 swap 和 selinux 和 防火墙
vim /etc/fstab    # 注释swap行
vim /etc/selinux/config # 改为disable
systemctl disable firewalld.service # 关闭防火墙

# 添加k8s源
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

# 添加k8s配置文件
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

# 更新yum源为阿里或者其他源
yum claen all && yum makecache

# 安装kubeadm
yum install -y kubelet-1.18.2-0 kubeadm-1.18.2-0 kubectl-1.18.2-0 --disableexcludes=kubernetes

# 使用kubeadm快速部署k8s
kubeadm init --image-repository registry.aliyuncs.com/google_containers --kubernetes-version=v1.18.2 --pod-network-cidr=10.244.0.0/16

# 根据部署完成后提示进行添加文件和集群信息

# 加载calico镜像
docker load -i calico_v3
# 修改calicoyaml文件,指定本机虚拟网段和k8s集群网段
sed -i 's/10.211.0.0/10.244.0.0/g' calico_v3.10.yaml

# 常用命令
kubectl get nodes   # 查看节点信息
kubectl cluster-info 
kubectl version kubectl api-versions 
kubectl config view 

# 删除节点
kubectl drain vms12.rhce.cc --delete-local-data --force --ignore-daemonsets 
kubectl delete node vms12.rhce.cc

# k8s节点监测软件
heapster

# 安装metric server

--------------------------------------------
namespace ns
--------------------------------------------
# 不同的namespace之间互相隔离
kubectl get ns # 查看ns
kubectl get pods -n xxx   # 指定查看ns中的pods
kubectl config get-contexts
kubectl config set-context 集群名 --namespace=命名空间
kubectl config set-context --current --namespace=命名空间
kubectl create ns xxx
kubectl delete ns # 如果ns里有pod,删除后里面东西会一起删除
kubectl get pods --all-namespace

kube-system # 系统命名空间,用来存放k8s系统pod

/etc/kubernetes/manifests # 目录下存放主要配置信息
systemctl restart kubelet # 重启kubelet后生效配置信息

--------------------------------------------
多集群切换
--------------------------------------------
~/.kube/config # 进行配置修改集群信息
kubectl config get-contexts # 查看集群信息
kubectl config use-context # 切换集群

--------------------------------------------
etcd  # 分布式数据库
--------------------------------------------
ETCD集群是一个分布式系统,使用Raft协议来维护集群内各个节点状态的一致性。 
主机状态 Leader, Follower, Candidate
当集群初始化时候,每个节点都是Follower角色
通过心跳与其他节点同步数据
当Follower在一定时间内没有收到来自主节点的心跳,
会将自己角色改变为Candidate,并发起一次选主投票
配置etcd集群,建议尽可能是奇数个节点,而不要偶数个节点

/var/lib/etcd/xxx # etcd数据存放位置
/etc/etcd/etcd.conf # etcd配置文件

# etcd集群配置
# member
ETCD_DATA_DIR="/var/lib/etcd/cluster.etcd" 
ETCD_LISTEN_PEER_URLS="http://192.168.26.61:2380,http://localhost:2380" 
ETCD_LISTEN_CLIENT_URLS="http://192.168.26.61:2379,http://localhost:2379" 
ETCD_NAME="etcd-61" 
# clustering
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.26.61:2380" 
ETCD_ADVERTISE_CLIENT_URLS="http://localhost:2379,http://192.168.26.61:2379" 
ETCD_INITIAL_CLUSTER="etcd-61=http://192.168.26.61:2380,etcd- 62=http://192.168.26.62:2380,etcd-63=http://192.168.26.63:2380" 
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" 
ETCD_INITIAL_CLUSTER_STATE="new"

# 参数意义
ETCD_NAME 节点名称,默认为default
ETCD_DATA_DIR 服务运行数据保存的路径
ETCD_LISTEN_PEER_URLS 监听的同伴通信的地址,比如http://ip:2380,如果有多个,使用逗号分隔。需要 所有节点都能够访问,所以不要使用 localhost!
ETCD_LISTEN_CLIENT_URLS 监听的客户端服务地址
ETCD_ADVERTISE_CLIENT_URLS 对外公告的该节点客户端监听地址,这个值会告诉集群中其他节点。 ETCD_INITIAL_ADVERTISE_PEER_URLS 对外公告的该节点同伴监听地址,这个值会告诉集群中其他节点 ETCD_INITIAL_CLUSTER 集群中所有节点的信息,格式为
ETCD_INITIAL_CLUSTER_STATE 新建集群的时候,这个值为 new;假如加入已经存在的集群,这个值为 existing。
ETCD_INITIAL_CLUSTER_TOKEN 集群的ID,多个集群的时候,每个集群的ID必须保持唯一

etcd member list # 查看集群成员信息
etcd member remove xxxx # 删除集群成员

所有etcd节点版本要保持一致
版本3中,etcd内部存储使用键值对形式

# vim快速替换
%s/old/new/g

# etcd新增节点
ETCD_INITIAL_CLUSTER_STATE 新建集群的时候,这个值为 new;假如加入已经存在的集群,这个值为 existing
etcdctl member add etcd-64 http://192.168.26.64:2380

# etcd管理
export ETCDCTL_API=3
etcdctl put k1 vv1
etcdctl get k1
etcdctl snapshot save snap1.db etcdctl del k1 # 快照
etcdctl help snapshot save
etcdctl --cacert=domain1.crt --cert=node1.pem --key=node1.key - -endpoints=127.0.0.1:2379 snapshot save snap1.db
etcdctl --endpoints=127.0.0.1:2379 snapshot save snap1.db 

--------------------------------------------
pod
--------------------------------------------
创建pod的2种方式
1.写yaml文件(推荐)
    a.复制模板并修改
```
apiVersion: v1
kind: Pod
metadata:
  name: pod-1
  labels:
      app: myapp
spec:
  containers:
  - name: hello
    imagePullPolicy: IfNotPresent # 设置下载镜像模式
    image: nginx
    resources: {}
    command: ["sh","-c","sleep 1000"]
  dnsPolicy: ClusterFirst
  restartPolicy:Always
    # command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
```
    b.可以使用命令行来生产

2.可以使用命令行的方式
# --dry-run=client 并不真正运行
kubectl run pod1 --image=nginx --dry-run=client -o yaml > pod1.yaml

# pod的基本操作

kubectl exec 命令
kubectl exec -it pod sh #如果pod里有多个容器,则命令是在第一个容器里执行 
kubectl exec -it demo -c demo1 sh
kubectl describe pod pod名 
kubectl logs pod名 -c 容器名 #如果有多个容器的话 
kubectl edit pod pod名
kubectl cp /xxx/xx pod_name:/xxx/xx # 拷贝物理机至pod
kubectl cp pod_name:/xxx/xx /xxx/xx # 拷贝pod至物理机

Pending pod 因为其他的原因导致pod准备开始创建 还没有创建(卡住了) 
Running pod已经被调度到节点上,且容器工作正常
Completed pod里所有容器正常退出 
error
CrashLoopBackOff 创建的时候就出错,属于内部原因 
imagePullerror 创建pod的时候,镜像下载失败

一个pod里,可以有多个容器,
其中第一个容器叫做主容器,其他容器叫sidecar
kubectl get pod pod_name -c container_1 # 进入pod的指定容器里

初始化容器没有运行完,才会运行常规容器
初始化容器从上到下依次运行
如果某初始化容器运行失败,后续的初始化容器不再运行

# 静态pod
修改完静态pod yaml文件后,systemctl restart kubelet 重启立即生效
systemctl status kubelet # 查看kubectl的状态和配置文件地址

# 对node设置标签
kubectl label nodes xx aaa=xx
kubectl label nodes --all aaa=xx # 对所有节点设置标签
kubectl label nodes --all aaa-   # 取消标签
kubectl edit nodes xxx

# 查询nodes运行信息
kubectl get nodes xxx -o wide

# 查询pod运行信息
kubectl get pods xxx -n xxx -o wide

# 设置pod在指定的标签上运行
1.先对某节点打上标签
2.修改yml中,修改字段 nodeSelector:指定标签信息

# 如果某node需要维护
1.先将某节点cordon,设置为不可调度模式
2.然后再进行维护
3.其上面已经运行的pod,还是继续运行
kubectl uncordon node_name # 恢复调度模式

kubectl drain vms11.rhce.cc --ignore-daemonsets
kubectl uncordon vms11.rhce.cc
用于节点的维护
如果一个节点被设置为drain,则此节点不再被调度pod, 
且此节点上已经运行的pod会被驱逐(evicted)到其他节点
drain包含: cordon、evicted

# 节点污点设置Taint
kubectl taint nodes node_name keyxx=valuexx:NoSchedule
kubectl taint nodes node_name keyxx- # 取消污点
# 容忍污点,tolerations字段增加信息可容忍污点
tolerations:
- key: "keyxx" 
  operator: "Equal"
  value: "valuexx" 
  effect: "NoSchedule"
containers:
  - name: myapp-container
  image: nginx

--------------------------------------------
存储管理
--------------------------------------------
本地存储:缺点:pod停止后重新拉起,漂移,导致文件访问异常
  emptyDir    
  hostPath
网络储存:缺点,存储访问的人员复杂,容易误操作
  nfs
  iscsi
  ceph
  glusterfs
持久性存储:


# emptyDir:
volumes:
  - name: volume1
  emptyDir: {} containers:
  - name: demo1
  image: busybox
  command: ['sh','-c','sleep 5000'] 
  volumeMounts:
  - mountPath: /xx
name: volume1

# nfs使用,容易有性能瓶颈,nas存储
yum install nfs-u* -y

apiVersion: v1 
kind: Pod 
metadata:
  labels: 
    run: nginx
  name: nginx spec:
volumes:
  - name: nfs
  nfs:
  server: 192.168.26.102 
  path: "/123"
  containers:
    - image: nginx
    name: nginx 
    volumeMounts: 
      - name: nfs
      mountPath: "/usr/share/nginx/html"

# iscsi使用,san存储,课后不用练习
yum install target* -y
yum install iscsi* -y

apiVersion: v1 
kind: Pod 
metadata:
  name: iscsipd 
spec:
  containers:
  - name: iscsipd-rw
    image: nginx 
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - mountPath: "/mnt/iscsipd"
      name: iscsipd-rw 
  volumes:
  - name: iscsipd-rw
    iscsi:
      targetPortal: 192.168.26.102:3260 
      iqn: iqn.2018-10.cc.rhce:disk 
      lun: 0
      fsType: xfs
      readOnly: false

# pv,持久性存储
apiVersion: v1
kind: PersistentVolume 
metadata:
  name: pv01 
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  storageClassName: slow  # 
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /zz
    server: 192.168.26.1

# pvc和pv关联的时候,有两个重要的参数
1.accessmode
ReadWriteOnce
ReadOnlyMany
ReadWriteMany

2.capacity
容量--配额--最多只能写最大的数据

# 一个pv只能匹配一个pvc
storageClassName # 只有这个值相同的情况,才会继续匹配
# pvc容量不能大于pv的容量

pv回收策略
• Recycle --会删除数据
  • 会生成一个pod回收数据
  • 删除pvc之后,pv可复用
  • pv状态由Released变为Available
• Retain--不回收数据
  • 但是删除pvc之后,pv依然不可用
  • pv状态长期保持为 Released


--------------------------------------------
密码管理
--------------------------------------------
kubectl create secret generic mysecret1 --from-literal=user=tom --from- literal=password1=redhat --from-literal=password2=redhat

主要有两种方式引用secret
1.变量的方式进行引用(主要用这种方式引用居多)
2.卷的方式进行引用

kubectl create secret generic --help

apiVersion: v1 
kind: Pod 
metadata:
  name: mysql 
  labels:
    name: mysql spec:
containers:
- image: hub.c.163.com/library/mysql:latest
  name: mysql 
  ports:
  - containerPort: 3306 
    name: mysql
  env:
  - name: MYSQL_ROOT_PASSWORD
  valueFrom:
    secretKeyRef:
      name: mysecret1 
      key: password1

kubectl create configmap --help 


configmap he secret 实际上一样
secret对内容进行了base64加密

也是有2种引用方式

--------------------------------------------
deployment: 控制器,管理pod
--------------------------------------------
pod是不稳定,不健壮的

控制器:deployment/replicationcontroller/replicasets

kubectl create deployment dep_name --image=nginx --dry-run(模拟创建)=client -o yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: dep1
  name: dep1                    # devlopment的名字
spec:
  replicas: 1                   # 副本数
  selector:
    matchLabels:
      app: dep1
  strategy: {}
  template:                        
    metadata:
      creationTimestamp: null    # 时间戳,可不用
      labels:                    # 定义pod标签
        app: dep1    
    spec:
      containers:
      - image: nginx
          imagePullPolicy: IfNotPresent
        name: nginx
        resources: {}
status: {}

matchLabels需要和template中的labels中保持一致

# 修改deployment副本数
1.命令行修改
2.在线修改
3.修改yaml文件

# 命令行在线修改
kubectl scale deployment xxx --replicas=数量

# 在线修改副本数
kubectl edit deployment.apps xxxx

# 重新导出yaml文件
kubectl get deployment.apps xxx -o yaml > xxx.yaml

# 升级镜像
kubectl set image deploy deploy_name container_name=new_container_name --record # 保留镜像更新记录
该过程会先删除原有容器,再创建新的容器

# 可查看做了多少次修改
kubectl rollout history deploy pod_name

# 回滚
kubectl rollout undo deployment name --to-revision=xxx

或者直接修改yaml文件来进行镜像升级

滚动升级
rollingUpdate:
  maxSurge: xx%        # 在升级过程中一次升级几个,可以按百分比或者指定个数
  maxUnavaliable: xx%    #在升级过程中,只能有1个不可用一次性删除多少个pod,可以按百分比或者指定个数

HPA
通过检测pod CPU的负载,解决deployment里某pod负载太重,动态伸缩pod的数量来负载均衡

kubectl autoscale deployment nginx --min=2 --max=10 --cpu-percent=80

HPA和手工调整,没有优先级

--------------------------------------------
其他一些控制器
--------------------------------------------
daemonset
应用场景
1.运行集群存储 daemon,例如在每个 Node 上运行 glusterd、ceph
2.在每个 Node 上运行日志收集 daemon,例如fluentd、logstash
3.在每个 Node 上运行监控 daemon,例如 Prometheus Node Exporter、collectd、 Datadog 代理、New Relic 代理,或 Ganglia gmond

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: busybox
spec:
  selector:
    matchLabels:
  app: busybox
  template:
    metadata:
      labels:
        app: busybox
    spec:
      containers:
      - name: busybox
        image: busybox command:
        - sleep
        - "36000"

可在yaml上写上标签注明在哪个节点上生成pod

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: busybox
spec:
  selector:
    matchLabels:
  app: busybox
  template:
    metadata:
      labels:
        app: busybox
    spec:
      nodeSelector:
        lable_xxx: xxx
      containers:
      - name: busybox
        image: busybox command:
        - sleep
        - "36000"

ReplicationController (RC)控制器

yaml文件类似deploymentyaml类型
kubectl scale rc nginx --replicas=10 # 调整副本数

ReplicaSet(rs)控制器
kubectl scale rs nginx --replicas=10

--------------------------------------------
健康性检查
--------------------------------------------
探测的目的
deployment只能保证pod的正常运行
pod内部的状态需要probe来进行探测
当probe监测到此问题,会认为pod出现了问题

1.liveness probe
  command
  http get
  tcp socket

# 1.livenessProbe
apiVersion: v1 
kind: Pod 
metadata:
  labels:
    test: liveness
  name: liveness-exec 
spec:
  containers:
  - name: liveness
  image: busybox args:
  - /bin/sh
  - -c
  - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 10 
  livenessProbe:
    exec: command:
    - cat
    - /tmp/healthy
    initialDelaySeconds: 5 #容器启动的5s内不监测 
    periodSeconds: 5 #每5s钟检测一次

# 2.httpGet/tcp
  livenessProbe:
    failureThreshold: 3
    httpGet:
      path: /index.html 
      port: 80
      scheme: HTTP

  livenessProbe:
    failureThreshold: 3
    tcpSocket:
      port: 80

initialDelaySeconds:容器启动后第一次执行探测是需要等待多少秒。
periodSeconds:执行探测的频率,默认是10秒,最小1秒。
timeoutSeconds:探测超时时间,默认1秒,最小1秒。
successThreshold:探测失败后,最少连续探测成功多少次才被认定为成功,默认是1,对于liveness必须 是1,最小值是1。
failureThreshold:当 Pod 启动了并且探测到失败,Kubernetes 的重试次数。存活探测情况下的放弃就意味 着重新启动容器。就绪探测情况下的放弃 Pod 会被打上未就绪的标签。默认值是 3。最小值是 1
https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-liveness-readiness- startup-probes/#configure-probes

2.readiness probe
# liveness通过重启来解决问题
# readiness检测到问题,并不重启
# 只是svc接收的请求不再转发给此pod

--------------------------------------------
job 
cronjob
--------------------------------------------
job 用来执行单次的任务
cronjob 用来执行计划任务

# job
job的restart策略只能是:
Nerver 只要任务没有完成,则是新创建pod运行,直到job完成会产生多个pod
OnFailure 只要pod没有完成,则会重启pod,直到job完成

apiVersion: batch/v1 
kind: Job
metadata:
  name: job1 
spec:
  backoffLimit: 6 # 重启次数
  completions: 1 
  parallelism: 1  # 并行,同时创建几个pod来执行任务
  template:
    metadata: 
      name: pi
    spec:
      containers:
        - name: hello
        image: busybox
        command: ["sh","-c","echo hello world!"] 
      restartPolicy: Never

# cronjob
和crontab一样   分 时 天 月 周 命令  如果没写的话,则表示“每”

启用cronjob
vim /etc/kubernetes/manifests/kube-apiserver.yaml 
添加
- --runtime-config=batch/v2alpha1=true

--------------------------------------------
SVC
--------------------------------------------
# svc本质上是一个负载均衡器,实现负载均衡:
iptables
ipvs # 性能更优
kube-proxy # 可选两种负载模式

创建svc的时候,可以基于pod来做,也可以基础deployment来做
基于pod,在svc里指定,我们需要关联哪些标签
基于deployment做,svc会关联deploy里定义pod的哪些标签

kubectl expose deployment xx --name=svc1 --port=80 --target-port==80
target-port # 后端端口
port # svc监听端口
svc的ip也是集群可见的

服务的发现
1.cluster IP

2.变量的方式 $(SVCNAME_SERVICE_HOST/SVCNAME_SERVICE_PORT)
# 变量的方式存在问题:
# 1.智能获取相同ns里的变量
# 2.变量的获取有先后顺序,引用的变量必须要先创建

3.dns的方式 # 推荐这种方式进行访问
# 1.在同一个命名空间里,一个服务访问另外一个服务的时候,可以直接通过服务名来访问
# 2.如果是不同的命名空间,可以通过 服务名.命名空间名 来访问
# 服务名.命名空间.svc.cluster.local
docker pull busybox:1.28.3
kubectl run busybox --rm -it --image=busybox:1.28.3 sh

服务发布
# 让集群之外的主机能访问服务
clusterIP
NodePort
和hostPort不同:
# 1.hostPort对pod来做,nodePort对svc来做
# 2.nodeport可以做负载均衡,hostport不可以

ingress 服务的发布
# 1.先创建pod
# 2.然后创建SVC关联pod
# 3.然后创建ingress组件pod
# 4.然后创建ingress规则pod,编辑规则

apiVersion: extensions/v1beta1 
kind: Ingress
metadata:
  name: myingress 
spec:
  rules:
  - host: www.rhce.cc
    http: 
      paths: 
      - path: /
        backend: 
        serviceName: nginx2 
        servicePort: 80
      - path: /cka 
        backend:
        serviceName: nginx2 
        servicePort: 80


--------------------------------------------
网络
--------------------------------------------
网络策略的设置

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata: 
  name: policy_tst
spec:
  podSelector: 
  matchLabels:
    aa: aa1
  policyTypes:
  - Ingress  # 入流量的策略
  ingress:  
  - from:
    - podSelector: # 允许通过的标签匹配
        matchLabels:
          xx: xx 
    - ipBlock:    # 允许访问的地址段
      cidr: 0.0.0.0/0 
    ports:
    - protocol: TCP 
    port: 80

--------------------------------------------
helm
--------------------------------------------

helm/tiller
helm # 客户端工具,发送各种请求
tiller # 服务器端
tiller.yaml # 修改3个地方
# 1.apiversion
# 2.seletor
# 3.image: 地址

helm仓库下载:

helm init --client-only --stable-repo-url http://mirror.azure.cn/kubernetes/charts/ http://mirror.azure.cn/kubernetes/charts/
https://apphub.aliyuncs.com
helm repo list
helm repo remove stable
helm repo add ali https://apphub.aliyuncs.com

kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller

# helm 权限问题
https://stackoverflow.com/questions/54683563/helm-error-error-the-server-has-asked-for-the-client-to-provide-credentials

helm delete --purge xxx # 深度删除

包下载的位置:/root/.helm/cache/archive

helm fetch xxx # 下载包

解压后生成的文件夹叫做:chart

chart包里一般包含
# 1.readme文件
# 2.chart.yaml 记录chart属性信息
# 3.values.yaml 核心配置文件
# 4.templates 创建pvc、deployment等yaml文件,这些yaml文件取值均来自于value.yaml中

helm install --name xx ./

helm package xxx # 打包

搭建私有仓库
1.需要一个web服务器
2.

自定义chart 
helm create mychart
检测语法
helm lint mychart
helm install --dry-run mychart --debug 
helm install mychart

推送到源里
helm package mychart # 打包
mkdir myrepo
mv mychart-0.1.0.tgz myrepo
docker run -dit --name=c1 -p 8080:80 -v /data:/usr/share/nginx/html docker.io/nginx 
helm repo index myrepo/ --url http://192.168.26.52:32419/charts 
然后把myrepo拷贝过去 cp myrepo/* /data/charts/


--------------------------------------------
权限管理
--------------------------------------------
kube自带证书位置:
/etc/kubernetes/pki

登录方式:
1. kubeconfig 
# kubeconfig 文件位置:~/.kube/config
# 该配置文件和 /etc/kubernetes/admin.conf一样
2. 用户名和密码方式登录:
  1:user account
  2:service accounte


# kubeconfig方式进行登录
1.生成特定权限的kubeconfig
# 生成私钥
openssl genrsa -out client.key 2048
# 通过私钥生成一个证书请求文件
openssl req -new -key cliient.key -subj "/CN=mary" -out client.csr
# 指定路径参数
dir=/etc/kubernetes/pki/
# 颁发证书
openssl x509 -req -in /ca1/client.csr -CA $dir/ca.crt -CAkey $dir/ca.key -CAcreateserial -out /ca1/client.crt -days 3650
# 拷贝证书
cp $dir/ca.crt ./
# 对用户进行授权
kubectl create clusterrolebinding cluster-test2x --clusterrole=cluster-admin --user=mary
# 开始以mary用户创建kubeconfig文件
# 新建配置文件config1
kubectl config --kubeconfig=config1 set-cluster cluster1 --server=https://192.168.48.142:6443 --certificate-authority=ca.crt --embed-certs=true
kubectl config --kubeconfig=config1 set-credentials admin1 --client-certificate=client.crt --client-key=client.key --embed-certs=true

# 引用kube配置文件
export KUBECONFIG=xxx
# 切换命名空间
kubectl config set-context context1

1.以mary用户生成证书
2.用此证书生成授权
3.创建kubeconfig文件,以mary用户证书关联


# 用户名密码进行登录
1. basic-auth-file 输入用户名和密码方式
2. token-auth-file 输入token进行验证

# basic-auth-file 输入用户名和密码方式
# user account方式进行登录

1. 修改api配置文件
vim /etc/kubernetes/manifests/kube-apiserver.yaml
# 增加此段配置,地址为此目录下
- --basic-auth-file=/etc/kubernetes/pki/aa.csv
2. aa.csv中添加用户
redhat,admin,1
redhat,tom,2
redhat,bob,3
3. 重启kubelet
systemctl restart kubelet
4. 对用户进行授权
kubectl create clusterrolebinding cluster-test2 --clusterrole=cluster-admin --user=admin
5. 登录测试
/tmp/kubectl -s="https://192.168.48.142:6443" --username="admin" --password="redhat" get pods -n kube-system
/tmp/kubectl -s="https://192.168.48.142:6443" --insecure-skip-tls-verify=true --username="admin" --password="redhat" get pods -n kube-system

# service account方式进行登录 sa
每个namespace里,都有一个default
pod里的进程以哪个sa来运行
可以对sa来授权

# 授权authorization
- --authorization-mode=Node,RBAC
- --authorization-mode=AlwaysAllow #允许所有请求
- --authorization-mode=AlwaysDeny #拒绝所有请求 
- --authorization-mode=ABAC
Attribute-Based Access Control 不够灵活放弃
- --authorization-mode=RBAC
Role Based Access Control # 目前主流的认证规则
- --authorization-mode=Node 
Node授权器主要用于各个node上的kubelet访问apiserver时使用的,其他一般均由RBAC授权器来授权

# RBAC认证的基于命名空间来做授权
1.clusterrolebinding # 全局
2.rolebinding

# rolebinding
kind: Role
apiVersion: rbac.authorization.k8s.io/v1 
metadata:
  name: pod-reader 
rules:
- apiGroups: [""] # api-version父子级
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

# 权限 get/watch/list/patch/delete/create

kubectl create rolebinding mybinding --role=pod-readr --user=tom

# clusterrolebinding 
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1 
metadata:
  name: reader 
rules:
- apiGroups: [""] # api-version父子级
  resources: ["pods"]
  verbs: ["get", "watch", "list", "create", "delete"]
- apiGroups: ["app"] # api-version父子级
  resources: ["deployment", "deployment/scale"]
  verbs: ["get", "watch", "list", "patch", "create", "delete"]

kubectl create clusterrolebinding clusterrole_tst --clusterrole=reader --user=tom

# 每创建一个sa,就会以此sa自动创建一个secret
kubectl create clusterrolebinding mybinding --clusterrole=reader --serviceaccount=default:sa-tst
# ns:sa_name

pod里的进程默认是defalut这个sa来运行

先创建user或者sa,然后再创建权限,再对权限和角色进行一个绑定

# 配置dashboard
1.先下载镜像

2. 创建pod 
apiVersion: v1
kind: ServiceAccount 
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: admin
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1 
kind: ClusterRoleBinding
metadata:
  name: admin 
roleRef:
  apiGroup: rbac.authorization.k8s.io 
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin
  namespace: kube-system

3.# 复制token
kubectl describe secrets admin-token-w9vvf -n kube- system
4.把token复制到 kubeconfig文件最下面
kubectl describe secrets admin-token-6d5h5 -n kube-system

--------------------------------------------
资源限制
--------------------------------------------
在kubernetets系统上,1个单位的CPU相当于虚拟机上的一颗虚拟CPU (vCPU)
或者物理机上的一个超线程(HyperThread,或者称一个逻辑 CPU),
它支持分数计量方式,一个核心(1 core)相当于1000个微核心 (millicores),
因此500m相当于是0.5个核心,即二分之一个核心。

1.resources方式限制
request: # 资源要求的最小值
limits: # 资源要求的最大值

resources:
  name: volume1
  requests:
    memory: "256Mi"
    cpu: "500m"
  limits:
    memory: "512Mi" 
    cpu: "1000m"

2.limitRange
apiVersion: v1 
kind: LimitRange 
metadata:
  name: mem-limit-range spec:
limits:
  - default:
  memory: 512Mi 
  defaultRequest: 
  memory: 256Mi
  type: Container

3.resourcequota
# limitrange 用来限制每个pod的资源
# resourcequtoa 用来限制项目里可以使用多少资源

apiVersion: v1
kind: ResourceQuota 
metadata:
  name: compute-resources 
spec:
  hard: # 强制限制
    pods: "4"
    requests.cpu: "1" 
    requests.memory: 1Gi 
    limits.cpu: "2" 
    limits.memory: 2Gi 
    requests.nvidia.com/gpu: 4 
    configmaps: "10" 
    persistentvolumeclaims: "4" 
    replicationcontrollers: "20" 
    secrets: "10"
    services: "10" 
    services.loadbalancers: "2"

--------------------------------------------
监控
--------------------------------------------
export收集数据 -》prometheus server数据汇总 -》grafana画图

helm fetch apphub/prometheus
不启用pvc,改成false
helm install --name=aaa .
修改clusterip为nodeport

搭建grafana
helm fetch azure/grafana --version=3.11.1
helm install --name=bbb .
修改clusterip为nodeport

--------------------------------------------
日志管理 ELK EFK
--------------------------------------------
Elasticsearch #是个开源分布式搜索引擎,存储日志及提供查询接口。
Logstash #是一个完全开源的工具,他可以对日志进行收集 发送给Elasticsearch.
Kibana #是一个开源和免费的,web界面的工具,可以让用户浏览Elasticsearch里的日志.

logstash性能低,消耗资源,且存在不支持消息队列缓存及存在数据丢失的问题 
所以logstash一般可以用fluentd或者filebeat替代

下载需要的yaml文件
wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/a ddons/fluentd-elasticsearch/es-statefulset.yaml
wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/a ddons/fluentd-elasticsearch/es-service.yaml
wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/a ddons/fluentd-elasticsearch/fluentd-es-configmap.yaml
wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/a ddons/fluentd-elasticsearch/fluentd-es-ds.yaml
wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/a ddons/fluentd-elasticsearch/kibana-service.yaml
wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/a ddons/fluentd-elasticsearch/kibana-deployment.yaml

先部署elasticsearch,确保pod正常运行 
再部署fluentd,确保pod正常运行 
最后部署kibana


--------------------------------------------
CI/CD/devops
--------------------------------------------
CI-CD可持续交付
提交代码-》gitlab-》构建-》测试-》编译-》推送-》交付

gitlab+jenkins+registry

--------------------------------------------
StatefulSet 控制器 sts
--------------------------------------------
deployment的pod删除后会自动再次生成新的pod,新的pod不会用到原有的存储
sts创建的pod被删除后会继续使用原有的pod

deployment等控制器 --通过svc连接,连接的pod不固定
sts连接到固定的pod
启动和关闭按指定的顺序

sts:
连接不同的存储 如果就想访问某pod,而不是其他的pod(因为pod连接不同的存储)

无头服务(headless service)
pod的IP是可变化的,可以通过pod.svc来访问pod 
ClusterIP=None
kubectl run busybox --rm -it --image=busybox:1.28.3 sh

--------------------------------------------
master负载均衡和高可用
--------------------------------------------
1.配置haproxy
2.配置三台ETCD
3.配置k8s集群
4.配置calico网络

--------------------------------------------
breeze部署k8s
--------------------------------------------
swapon -s # 关闭swap
yum install docker
systemctl enable docker --now

--------------------------------------------
exam train
--------------------------------------------
yum install bash-completion
vim /etc/profile
source <(kubectl completion bash)

以上内容自学记录,如有错误,还请指正。

love&peace

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐