Openshift是什么?能干什么?
所谓得Paas者得天下,Openshift是红帽的云开发平台即服务(PaaS)。
IT发展方向:容器化所有应用,目的实现DEVOPS,目前的几种实现方式:
1)AWS Devops
参考:https://www.sohu.com/a/213232086_411876
2)Openshift
3)RunC和Podman (Openshift4.1)
RunC 是一个轻量级的工具,只用来运行容器,podman是一个用于处理容器的开源Linux工具。
使用此类工具产品后使得代码的开发到构建应用成为一条龙服务
Openshift解决的问题:CI和CD无缝集成,开发和运维无缝集成。 要把代码变成可见的直观应用。
CI:持续化集成Git SVN。可以在git hub和docker hub上注册账号,只要在git一提交代码,就会自动生成镜像。
CD:持续部署(deployment)
Openshift是一个私有云,私有的PAAS云。是企业级平台。目前主流版本是3.9,4.1已经推出。4.1的区别就是底层容器是基于runC和podman,这两者是不许要单独启动进程的。
实现方式:AWS \ Openshift container platform \ Openshift.com
Openshift开源版的叫:Openshift origin。
Openshift=docker+k8s + oc
docker是k8s的一个低级别组件。docker是容器引擎的一种。容器是操作系统虚拟化,实际就是系统中的一个进程,只不过是被隔离的。
容器=linux+namespace+cgroup + selinux
(资源隔离)(资源限制)(安全)
容器的优点:轻量化、秒级启动,可扩展多个副本。原则是一个容器只运行一个应用。
一个企业版linux有4、5G,一个企业化linux容器只有200M。这是因为所有容器共享操作系统底层。如果是虚拟机的话,每个虚拟机都有自己的IO、网络、磁盘管理的底层,所以虚拟机和容器是不一样的。
K8S:作用就是容器编排。调度和高效管理容器,维护容器之间的亲戚关系(微服务架构)。
ansible:自动化运维的王者。从当前到未来,红帽几乎所有的产品部署都通过ansible。Openshift就是通过ansible部署的。
Openshift架构
Openshift基本概念复习(参见书上第九章)
容器=linux + namespace(资源的隔离,包括网络的隔离)+ cgroup(资源的限制) + selinux
容器实现了进程、网络、ipc通信、文件系统的隔离。是一个轻量级的沙箱,彼此隔离,互不可见的。
容器的好处就是把环境都准备好了,每个应用只需要连着环境整个拿下来就好了。
容器需要docker engine才可以运行。docker和docker engine都可以从docker.io上下载。它们对上层的K8S或mesos都是通用的。
容器每次更新也都会生成一个新的版本
因为微服务架构大行其道后,用虚拟机发现吃资源太多,所以出来了轻量化的容器化技术。从这点来说,zookeeper实现服务注册还是再上层的微服务架构。
容器可以帮助我们应对生命周期更短的应用,只要应用执行完成了,容器就停止了。
镜像(image):相当于虚拟机的模板
容器(container):相当于正在运行的虚拟机,镜像和模板是可以相互转化的。要想启动一个容器就得需要一个镜像。需要先把代码编译成镜像,再把镜像启动为容器。
仓库(Repository):集中存放镜像的服务器。分为公共的(docker hub,通过docker search就是在共有镜像仓库中查询。国内有网易蜂巢,各种镜像都有)和私有的(docker-registry-cli)。例如:docker-registry-cli registry.lab.example.com list all ssl |grep mysql
etcd:发现服务。键值数据库。是装在master服务器上,维护master和node之间的关系。一般大型生产环境中,为了保证高可用,一般需要3个master和3个etcd节点。
zookeeper和etcd是类似的,用于服务发现注册的服务,但是zk会注册接口,etcd只会注册master和node。但是一般来说,一个docker(一个node)只会暴露一个接口,其实是类似的。但是zk应该还有一些监控接口流量的功能吧。
POD:k8s的一个最小化单位。容器是包含在pod中的。pod是一个或多个容器的集合。pod包含了所有容器的所有属性,比如暴露出来的端口是什么之类的。
CI提交---->CD触发构建build---->根据代码语言,自动build POD,这个POD把代码编译成镜像,上传到Openshift内部的镜像仓库去。然后用这个镜像生成运行的POD容器。
要实验就是在git hub上创建项目,在docker hub创建项目,两个账号做关联,在git hub上提交后修改的代码后就会自动触发构建。
Service:容器运行的时候是在运行在POD内部的一个网络,与外部是隔离的。所以需要创建一个Service(SVC),把容器内部的网络暴露出来。
Route:创建路由,动态DNS泛解析的主机名。会分配泛解析的域名,指向pod内部的ip,这样原来的docker死了,新docker起来也不会影响服务高可用。
持久化:POD在运行时,默认容器里的数据是非持久化的,因此需要集成外部存储,来实现POD内部数据的持久化存储。Openshift内部的镜像仓库也是在POD中的,因此也是需要集成外部存储,Openshift实验环境是nfs存储。
Openshift提供三种主要build策略:docker build、Source-to-Image(S2I) build、Customer build
Image Stream是一组镜像的集合,是一个指针。比如一个Image Steam里面同时包含了php和mysql两个镜像。直接引用Image Stream就可以获取两个镜像。
是启动POD的时候,告诉POD镜像在哪里。其实就是一组配置文件。这是Openshift特有的。Openshift默认为用户定义了一系列开箱即用的Image Stream。同时还指定了容器使用了哪些镜像。
docker file:是用来配置docker所需要的运行环境(比如PHP编译器)的。
Labels是用于区分Pod、Service、Replication Controller的K/V键值对。
k8s没有角色管理、监控,迁移,可用性,扩展,openshift都集成了。
Openshift中的资源(Openshift的所有资源都是由namespace隔离的):
node:服务器节点
POD:POD是容器的集合,POD包含容器
LABEL:标签
PV:持久化卷,Openshift所管理的一个物理存储对象,创建PV只能是集群管理员创建
PV跟PVC关联:PVC是租户层级的一个对象 pvc:PersistentVolumnClaim
SVC:service。pod get svc
ROUTE:路由。有三种类型:Edge Termination(流量在到达pod之前,由route的pod生成TLS加密。必须将证书配置到路由中。否则使用默认证书。相当于https)、Passthrough Termination(加密流量直接发送到目的地,直接发送到pod中)、Re-encryption Termination(重新加密,请求丢给pod以后,在pod内部通信仍然加密)
RC:Replication Controller:POD的副本数量。K8S会始终保证这个数量稳定。修改RC属性不用重启,因为会有rolling这个机制。
DC:Deploy Config部署的属性
BC:Build config构建的属性
oc logs -f bc/hello —> s2i的过程
project:一个项目就是一个命名空间,应用一定要放在项目下创建
yaml文件:创建POD、route的命令集合
模板:是一系列pod、service、expose的总集合。可能是以json格式存储
SCC:Security Context Constraints。SCC限制了容器内启动用户的UID范围。普通用户创建的项目,都属于resticted,这个组不允许容器以root用户运行,如果要容器以root用户权限运行
edge:一种通信方式,就是https。客户端到pod是加密的。
Openshift构建和部署也是使用不同的pod去完成:
[root@master ~]# oc get sa -n demo
NAME SECRETS AGE
builder 2 26m S2I
default 2 26m 用于运行容器
deployer 2 26m 部署容器
Linux命令:
top
查看资源使用情况
df -h
在容器里看到的容量信息是假的
curl http://ip:port/***
可以直接访问镜像
登陆到那个服务器上以后
netstat -tunpl | grep 30001
可以检查端口是否正常打开
容器相关命令:
查找镜像和容器:
docker-registry-cli registry.lab.example.com list all ssl | grep mysql
对于外部镜像仓库的镜像,需要通过第三方命令查找。
cli是client,代表命令行
docker-registry-cli registry.lab.example.com search mysql ssl
效果跟上面一样,不过通过这种方式可以看到包的版本号等信息
docker images
查看所有pull下来的镜像信息
docker ps -a
显示所有运行过的容器进程
docker search
查询dock hub上的镜像
运行容器
docker run --name mysql -d -it -e MYSQL_ROOT_PASSWORD= mypa55 docker.io/mysql(镜像路径)
-d是后台运行,否则会占住光标
-it是给it人员开个控制台
mysql是一种特殊的镜像,运行的时候要指定mysql的环境变量,运行时至少要指定root的密码。所以要用-e environment
也可以加 -p 3306:3306 就是把docker的3306端口映射到宿主机的3306端口。
但是这个端口即使暴露了,在本机上不能用localhost访问到,而是要通过桥接网管的地址才能访问。如果换一台机器,只要暴露了端口,就可以直接访问到了。
镜像路径和名字在最后
docker run --name mysql -d -it -e MYSQL_ROOT_PASSWORD=mypa55 -v /mysql:/var/lib/mysql/data:z url/mysql(镜像路径)
通过-v url:url:z来实现这个容器的持久化存储,前一个是宿主机路径,后一个url是容器内路径,z是自动配置selinux上下文
其中宿主机的url一定要有权限,否则要chmod 777 目录,或者生产上给27:27的权限,然后给它一个上下文。
docker restart mysql
重启容器
systemctl restart docker
重启docker服务
更新容器:(用于自定义镜像)
docker commit -m “update v2” -a richard rhel7 registry.lab.example.com/rhel7 -a
通过这个方法提交修改。-m 备注 -a 作者 然后是镜像url
commit只是放到本地。需要push才会上到镜像仓库。
docker history url/dockername
镜像每次commit以后也是会生成单独版本的。通过这个命令可以看到历史修改版本。
删除容器
docker rm PID(也可以用docker name)
删除docker
可以加-f参数强制删除
docker rmi dockername
删除本地镜像库中镜像
docker rm $(docker-ps -a -q)
删除所有docker
管理容器:
docker inspect dockername
是查看容器所有信息。特别是你要找一个docker的ip的时候,通过这个方式可以找到ip。
docker logs mysql
可以看到docker启动的日志。有报错在这里可以看。
docker exec -it mysql bash
进入docker查看
一些特殊的容器:
busybox这个容器可以提供cat、ls等基础命令的模拟。
docker tag usl/docker url/newname
可以重命名镜像
操作镜像仓库:
docker pull registry.lab.example.com/wordpress
来获取一个镜像,然后docker images就可以看到这个镜像
docker push URL/dockername:version
通过这个命令push到镜像仓库。:version是指定版本
容器保存成本地文件:
docker save -o dockername url/dockerName
保存容器成tar文件
docker load -i docker.tar
可以在其他环境load容器镜像
Docker相关配置文件:(ansible已经都配置好了,如果没有使用ansible,就需要手动配置)
/etc/sysconfig/config
BLOCK_REGISTRY='url;
阻止docker从哪些仓库下载
ADD_REGISTRY=’–add-registry url:port --add-registry url:port’
让docker从哪些源下载
INSECURE_REGISTRY=’–’
没有ssl就要加这个选项。
/etc/sysconfig/docker-storage-setup
指定docker镜像存在哪个磁盘上。存储是以瘦逻辑卷lvm的形式存储的。如果没有指定的话就会直接存在本地。
自定义镜像
书上P99
(通过docker file构建镜像)
第五章:P129
FROM rhel7:7.5
#镜像名称和版本
MAINTAINER Your Name
#镜像的作者
LABEL description=“描述信息”
#镜像的描述
ADD training.repo /etc/yum.repos.d/training.repo
从宿主机的目录拷贝一个目录到镜像出去
RUN yum -y update &&\
yum -y install httpd &&\
yum clean all
dock build时要运行的命令
不要写多个RUN,所有的命令写到一个RUN里面,因为每写一个RUN,就会多一个镜像的历史版本。
-y 执行非交互式的
CMD [“httpd”,"-D",“FOREGROUND”]
指定启动容器时执行的默认命令。-D和FOREGROUND是httpd的参数,大小写敏感。只能指定一个。如果写多个,只会执行最后一个。
expose 80
指定容器启动的时候的默认端口(Openshift默认是禁用80端口的)
配置完docker file以后,就要执行构建了
docker build -t url/dockerName .
.代表当前目录,如果指定目录就用-f
docker tag do285/apache registry.lab.example.com/my-apache
如果生成docker的时候dockername不规范,需要根据镜像仓库的路径进行tag以后才能push
P162
快速部署一个wordpress:前端需要一个wordpress服务和一个mysql服务
docker run -it --name=some-wordpress -p 8080:80 -d --link mysql:mysql docker.io/wordpress
–link可以让两个容器互通。后面两个参数,前面一个是别名,后面一个是对应的容器名称
OPENSHIFT
oc命令就是封装后的k8s命令。相当于k8s的kubectl。。。
安装Openshift
P169 P174
都是通过ansible跑playbook去安装,目前Openshift对应的ansible是2.4版本
使用ansible需要配置免密跳转
实验环境初始化:
在foundation宿主机上执行:
rht-vmctl reset all
重置初始化环境
安装docker:
sudo yum install ansible
安装ansible
ansible --version
可以看ansible的版本
ansible-playbook -v ping.yml
批量检查ansible要安装的机器是否ping的通
sudo yum install atomic-Openshift-utils
安装utils,安装了这个包以后才会得到ansible的playbook,包括docker和Openshift的安装程序的主包
lab install-prepare setup
需要在workstation上执行,得到do285-ansible课程目录,里面有ansible.cfg prepart_install.yml有这些才能安装ansible
进入~/DO285/labs/install-prepare/
ansible-playbook prepare_install.yml
执行ansible剧本
安装Openshift:
lab install-run setup
do285-ansible下是课程默认改好的文件inventory文件,cp到~/DO285/labs/install-run/下面
一定要在install-run这个目录下执行,因为ansible的配置文件ansible.cfg、inventory在这个目录下
ansible-playbook /usr/share/ansible/Openshift-ansible/playbooks/deploy_cluster.yml
安装完以后会把master变成Openshift的控制节点,node1、node2是计算节点,workstation是Openshift的客户端
Openshift安装配置
vim prepare_install.yml
配置docker证书、存储,确保能访问docker服务
Openshift_master_default_subdomain=apps.lab.example.com
用于然后要配置网络
配置角色:
用户管理角色管理:
P369
ansible安装时使用的是apache的虚拟用户。是配置在authentication_vars.txt里。
虚拟用户的密码需要通过openssl passwd命令去生成,在Openshift下就是htpasswd
Service Account是Openshift中一种特殊用户帐号,这些帐号专门用户容器应用交互。
当用户创建一个新的项目时,Openshift都会为该项目创建一系列服务帐号
以下是系统内置的一些角色
system:admin 集群管理员。只可以在master节点上登入
admin:在未授权之前只是一个普通用户,需要通过system:admin给其授权cluster-admin以后才能在非master节点上执行admin的操作
view:只能查看某项目。
创建账户:
登陆到master账户上
vim /etc/origin/master/master-config.yaml
搜索HT,上面一行file可以看到密码文件位置
cat /etc/origin/master/htpasswd
可以查看现有的用户和密码
htpasswd -b /etc/origin/master/htpasswd username pwd
/etc/origin/master/htpasswd是密码文件
-b参数是在同一行输入用户名和密码
oc adm policy add-cluster-role-to-user cluster-admin admin
这样给admin用户授权集群管理员的权限,这样就可以在非master节点使用集群管理员权限了。
要执行赋权命令,必须要保证自己是在master节点上,保证自己是system:admin,所以需要在master上:oc login -u system:admin
cat /etc/origin/master/htpasswd
可以看到所有用户和密文密码
oc login -u username -p pwd https://master.lab.example.com
https://master.lab.example.com是master节点的url
oc adm policy remove-cluster-role-from-group self-provisioner system:authenticated:oauth
用于取消普通用户组新建项目的权限
命令用Tab键可以部分补全
oc adm policy add-role-to-user admin user1 -n project1
针对project1赋予user1用户管理员的权限
oc adm policy add-role-to-user view user2 -n project2
针对project2赋予user2只可以查看的权限。(查看可以运行,不能管理和删除)
oc describe rolebinding
查看用户与角色的绑定关系
发布应用:
需要先登陆Openshift的节点,比如workstation或master(P200)
查看环境:
oc whoami
发布应用过程中最关键的是时时刻刻去确定我是谁,我用的项目是哪一个
oc project
查看当前所在的项目(namespace),所有namespace下的资源全都是隔离的。
oc login -u admin -p redhat https://master.lab.example.com
登陆到master节点
oc get nodes
看管理了几个物理机节点,需要用管理员执行
oc get pod --all-namespace
可以看到oc管理的pod,至少有5个:docker-registry-是命令行版的内部镜像仓库,registry是web版的内部镜像仓库,两个负载均衡的代理
pod内部的网络只有在集群内部才能访问。要创建service才能从外部访问。
–all-namespace 查看所有namespace的pod
oc get all
可以获取所有的资源信息
oc get pod -o wide
查看pod的详细信息。可以看到pod run在哪个服务器上
准备发布
oc new-project smoke-test
新建一个namespace
smoke-test是项目名称
–description=“testtest” 可以用来添加project的描述
镜像资源:
oc get is -n Openshift | grep python
查看所有带python的image stream资源
-n代表namespace 放在Openshift里所有项目都可以看到,也可以放到project1等其他项目名
创建应用:
通过源码创建应用:
oc new-app registry.lab.example.com/php:5.6~http://service.lab.example.com/php-helloworld --name hello
通过源码去创建镜像。用源码创建前提是php:5.6这个镜像已经存在了。
registry.lab.example.com/php:5.6是镜像地址和版本
http://service.lab.example.com/php-helloworld是源码地址
–name 是应用名称
new-app会自动创建出pod和service
通过镜像创建应用:
oc new-app --docker-image=registry.lab.example.com/Openshift/hello-Openshift --name=hello
执行后通过oc get pod,看到没有build的过程,因为是直接从镜像直接生成的
通过image stream创建应用
也可以通过oc new-app --name=hello -i php:7.0 http://registry.lab.example.com/scaling
-i是 image stream,跟~是一样的。
oc logs -f bc/hello
查看build config编译日志
管理pod:
oc rsh podname
登录到pod内部
oc edit rc hello-2
rc只是在部署的时候指定pod的数量
oc edit dc hello
部署好了以后可以编辑dc,或者界面来扩展pod。
也可以用oc scale --replicas=2 dc hello 来扩展pod
oc delete pod mysql
可以删除已启动的pod
创建服务:
oc get svc
查看service。创建了服务就是会对pod完成暴露,产生clusterIP,但是这个ip还是一个集群内部ip,这个ip会与pod的ip进行绑定。但是这个ip没有被暴露出来,必须要创建一个路由域名,才能从外部访问。
通过这个命令可以看自己要暴露的服务名。
oc edit svc hello
可以编辑网络端口
ClusterIP是pod里面的ip,需要expose端口以后才能从外部访问
通过配置nodePort可以直接暴露pod的端口,就类似于 -p 8080:80
网络配置:
创建路由:
svc仅仅是
需要创建route,将svc发布出来供外部用户连接。
有三种类型的route:
Edge Termination
流量在到达pod之前,由route的pod生成TLS加密。必须将证书配置到路由中。否则使用默认证书。
Passthrough Termination
加密流量直接发送到目的地,直接发送到pod中
Re-encryption Termination
重新加密,请求丢给pod以后,在pod内部通信仍然加密。
SDN的网络里什么要用VXLAN?
VXLAN是将一种协议封装在另外一种协议中传输。好处是我不用改变当前网络中的协议,就可以在另外一种网络中传输。是为了实现容器的跨主机和跨子网的通信。
ovs-subnet
扁平网络。这种配置下默认情况下各个pod之间网络是通的。
oc get route
查看现有的路由
oc expose svc hello --name=hello --hostname=hello.project1.apps.lab.example.com
将hello这个应用暴露一个域名
svc hello是指定要暴露的service的名字,
–name=hello是指定暴露出来的route的名字
–hostname是要暴露出来的域名
oc create route edge --service=hello --hostname=hello.apps.lab.example.com --key=hello.apps.lab.example.com.key --cert=hello.apps.lab.example.com.crt
创建一个edge类型的路由,这个命令跟上一个的区别是这个可以创建各种类型的路由。
edge是上面那种加密的路由,可以简单的理解成https
这里的key和cert都是通过openssl生成的秘钥文件。可以参考下面的题目。
curl -k -vvv https://hello.apps.lab.example.com
curl可以对服务进行调用。创建了路由以后,可以通过url访问。
访问https需要加-k
-vvv是查看详细信息
创建安全路由:
openssl genrsa -out example.key 2048
openssl x509 -req -days 366 -in example.csr -signkey example.key -out example.crt
迭代源码:
git clone http://services.lab.example.com/php-helloworld
把源码项目目录克隆下来
如果在workstation修改了源码
git add .
这样就把当前目录上传
git commit -m “备注”
提交代码
-m是message备注
git push
上传仓库
如果没有设置hook,需要手动触发更新
oc start-build bc/hello
这时候oc get pod就可以看到有多个编译版本
如果迭代版本,第一个pod会自动消失。
通过yaml文件创建资源
通过yaml文件可以创建pod、svc、pv、pvc等等各种资源。甚至可以直接使用template,就是一系列资源写在一个文件中,直接执行就可以一次性生成。template可以在图形化界面中看到。
oc create -f mysql-pod.yaml
通过yaml文件创建应用
oc create -f wordpress-mysql.json -n Openshift
将模板创建到共用namespace,所有项目可用。
oc eport
导出svc的yaml文件
oc get template
查看当前项目下的模板信息。
持久化存储
由于容器都是非持久化的,需要对容器内需要持久化的部分进行映射。包括内部镜像仓库,重启也就没有了。所以需要持久化。教学时使用的是NFSServer进行存储。
存储分为两层,系统级别PV(PersistentVolume)和项目级别的PVC(PersistentVolumeClaim)。一个PVC只能绑定到一个PV上面,PV会自动和容量最接近的PVC绑定。
创建存储资源一般通过yaml文件。格式比如:
[root@master ~]# oc create -f metrics-pv.yml
apiVersion: v1
kind: PersistentVolume
metadata:
name: metrics
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
nfs:
path: /OCP_metrics
server: services.lab.example.com
persistentVolumeReclaimPolicy: Recycle
oc create -f pv-mysql.yaml
通过yaml文件创建pv。由于pv是系统级别的资源,必须由管理员创建。
oc create -f pvc-mysql.yaml -n project1
通过yaml文件创建pvc
由于PVC是与项目绑定的。绑定时最好指定项目,或者检查目前所在的项目
oc get pv
一开始创建的pv是available的,需要和pvc绑定以后才会变成binding
oc get pvc
查看PVC
设置配额
资源限制:设置quotas
P506
ResourceQuota:资源限制针对整个project。
LimitRange:针对pod级别的
可以针对pod、svc、container做cpu、memory等各种限制
vi resource-quota.yml
到文档上找limit quota,配置复制下来
修改name,按照题目要求进行修改quota先知
oc create -f resource-quota.yml -n project3
创建quota
建议加资源限制的时候把namespace带上
oc describe resourcequota -n project3
可以看到验证所有的quota
vi limit-range.yml
在文档上找limit range,找一个有max和min和default的模板,配置复制下来
修改name,按照题目要求进行修改quota先知
oc create -f limit-range.yml -n project3
设置limit-range
设置监控
监控的三个组件:metrics subsystem 监控平台
heapster: 收集所有集群节点信息,要报收集的信息存放在支持长格式的存储中
hawkular: 收集度量的信息(metrics)存储的格式是基于时间的,所以要存到cassandra中去
cassandra: time series database 基于时间的数据库
具体操作查看书上P480 P494吧