在容器中尝试试用辅助车

使用Openshift或Kubernetes运行POD时,似乎可以通过使用Sidecar技术,在单个POD内运行多个容器的技术。

虽然”Sidecar”这个技术本身是个普遍概念,但是我认为最典型的应用方式是在istio上运行应用时,将应用代码的容器和由istio控制平面控制的Envoy以Sidecar方式一起部署,这样可以将用于载入istio服务网格的扩展与应用代码和容器分离,并进行构建。

换句话说,这意味着无需直接修改应用代码即可进行istio的扩展。在像单独运行应用代码的其他环境中,也可以重复使用相同的容器镜像或对扩展功能进行标准化,这带来了一些好处。如果有类似的场景能期望相同的效果,那么我认为可以积极利用这种方式。

在本文中,我打算真正尝试运行侧车容器。值得注意的是,该实验是根据网站learnk8s的文章《使用多容器Pod扩展Kubernetes上的应用程序》在Openshift Local(4.10.18)上进行的。

参考: 《OpenShift 本地环境准备》文章(OpenShift 本地环境是一个可以在桌面环境中运行的开发和运行验证的OpenShift环境。)

启动单个容器的Pod

首先,我们要验证一下简单的1个容器、1个pod的运行情况。在这里,我们将运行 elasticsearch 容器。

选项一:创建项目操作

使用开发者用户在本地打开Shift命令行界面登录。如果密码未更改,默认密码是”developer”。

$ eval $(crc oc-env)
$ oc login -u developer https://api.crc.testing:6443
Authentication required for https://api.crc.testing:6443 (openshift)
Username: developer
Password: *************
Login successful.
...
$ 

使用 oc new-project 命令创建一个用于实验的项目。这里指定的项目名称是 single-container-test。

$ oc new-project single-container-test
Now using project "single-container-test" on server "https://api.crc.testing:6443".

You can add applications to this project with the 'new-app' command. For example, try:

    oc new-app rails-postgresql-example

to build a new example application in Ruby. Or use kubectl to deploy a simple Kubernetes application:

    kubectl create deployment hello-node --image=k8s.gcr.io/e2e-test-images/agnhost:2.33 -- /agnhost serve-hostname

$ 

操作2: 准备清单

pod 部署时使用了 deployment 资源。

使用文本编辑器编辑以下类似的yaml文件。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: elasticsearch
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: elasticsearch
  template:
    metadata:
      labels:
        app.kubernetes.io/name: elasticsearch
    spec:
      containers:
        - name: elasticsearch
          image: elasticsearch:7.9.3
          env:
            - name: discovery.type
              value: single-node
          ports:
            - name: http
              containerPort: 9200
---
apiVersion: v1
kind: Service
metadata:
  name: elasticsearch
spec:
  selector:
    app.kubernetes.io/name: elasticsearch
  ports:
    - port: 9200
      targetPort: 9200

操作3:执行部署

使用oc apply命令进行部署。

$ oc apply -f elasticsearch.yaml
deployment.apps/elasticsearch created
service/elasticsearch created
$ 

执行oc get pod命令,确认状态为Runnning。如果状态不是Runnning,则重复执行oc get pod命令直到状态变为Runnning。

$ oc get pod -w
NAME                             READY   STATUS    RESTARTS   AGE
elasticsearch-5f9df6bcbf-cfghf   1/1     Running   0          11s
$ 

另外,由于在这里使用1pod 1container进行部署,所以READY栏的输出为1/1(即1个容器中有1个正在运行)。

操作4: 确认连接至Elasticsearch服务。

使用oc命令在同一项目中启动一个一次性容器,通过curl命令访问elastichsearch服务。如果一切正常,将从elastichsearch容器中收到响应。

$ oc run -it --rm --image=curlimages/curl curl -- curl http://elasticsearch:9200
If you don't see a command prompt, try pressing enter.
{
  "name" : "elasticsearch-5f9df6bcbf-cfghf",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "hg6FO5UWSOOlBz_5gAMaZw",
  "version" : {
    "number" : "7.9.3",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "c4138e51121ef06a6404866cddc601906fe5c868",
    "build_date" : "2020-10-16T10:36:16.141335Z",
    "build_snapshot" : false,
    "lucene_version" : "8.6.2",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}
Session ended, resume using 'oc attach curl -c curl -i -t' command when the pod is running
pod "curl" deleted
$ 

到目前为止,确认了简单的1个pod 1个容器的运行。
在这个实验中,elasticsearch容器使用9200端口进行http监听。

在下一个侧车案例中,我们将在此Elasticsearch容器的前端部署一个Nginx容器,并进行配置实验,以便通过HTTPS进行监听。

启动多个容器(侧边容器)的Pod

在与前述单一容器案例相同的流程中,我们将运行多容器Pod。在这里,我们在elasticsearch容器之前以类似代理的方式配置nginx容器,并可以观察到从使用HTTP进行监听的状态转变为使用HTTPS的情况。

创建项目操作

省略 Openshift 本地登录操作。

使用”oc new-project”命令创建实验用项目。此处指定的项目名称是multi-container-test。

$ oc new-project multi-container-test
Now using project "multi-container-test" on server "https://api.crc.testing:6443".

You can add applications to this project with the 'new-app' command. For example, try:

    oc new-app rails-postgresql-example

to build a new example application in Ruby. Or use kubectl to deploy a simple Kubernetes application:

    kubectl create deployment hello-node --image=k8s.gcr.io/e2e-test-images/agnhost:2.33 -- /agnhost serve-hostname

[toaraki@fedora proxy-test]$

选项1: 操作2: 准备清单

请在文本编辑器中准备以下类似的 YAML 文件。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: elasticsearch
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: elasticsearch
  template:
    metadata:
      labels:
        app.kubernetes.io/name: elasticsearch
    spec:
      containers:
        - name: elasticsearch
          image: elasticsearch:7.9.3
          env:
            - name: discovery.type
              value: single-node
            - name: network.host
              value: 127.0.0.1
            - name: http.port
              value: '9201'
        - name: nginx-proxy
          #image: nginx:1.19.5
          image: nginx:latest
          volumeMounts:
            - name: nginx-config
              mountPath: /etc/nginx/
              readOnly: true
            - name: certs
              mountPath: /certs
              readOnly: true
          ports:
            - name: https
              containerPort: 9200
      volumes:
        - name: nginx-config
          configMap:
            name: elasticsearch-nginx
        - name: certs
          secret:
            secretName: elasticsearch-tls
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: elasticsearch-nginx
data:
  #elasticsearch.conf: |
  nginx.conf: |
    user nginx;
    worker_processes auto;
    pid	/tmp/nginx.pid;

    events {
      worker_connections 1024;
    }

    http {
      proxy_temp_path /tmp/proxy_temp;
      client_body_temp_path /tmp/client_temp;
      fastcgi_temp_path /tmp/fastcgi_temp;
      uwsgi_temp_path /tmp/uwsgi_temp;
      scgi_temp_path /tmp/scgi_temp;
      server {
          listen 9200 ssl;
          server_name elasticsearch;
          ssl_certificate /certs/tls.crt;
          ssl_certificate_key /certs/tls.key;

          location / {
              proxy_pass http://localhost:9201;
          }

      }
    }
---
apiVersion: v1
kind: Service
metadata:
  name: elasticsearch
spec:
  selector:
    app.kubernetes.io/name: elasticsearch
  ports:
    - port: 9200
      targetPort: 9200

积分

    • containers のセクションに、elasticsearch と、nginx のエントリーしている(先ほどは1つだけ)

 

    • elastichsearch を、9201 、nginx を9200 ポートにそれぞれバインド

 

    • nginx のコンフィグは、ConfigMap で/etc/nginx/nginx.conf を渡している

参考サイトの方法だと、container上のディレクトリへのアクセス権限で不都合があったので、暫定的に動く方法に変更しました
準備中:nginxがopenshift で起動しない

secret オブジェクトを作成して、自己サーバ証明書を渡している

选项一:进行操作3:执行部署。

在侧边车(Sidecar)上配置的nginx将以https-proxy的方式运行,因此我们需要准备服务器证书并设置https通信。
首先,创建secret/elastichsarch-tls。请预先准备好服务器证书的文件(包括key、csr和crt文件)。

$ ls
tls.crt  tls.csr  tls.key
$ oc create secret tls elasticsearch-tls --key=./tls.key --cert=./tls.crt
secret/elasticsearch-tls created
$ 

然后,使用oc apply命令进行部署。

$ oc apply -f es-secure-deployment.yaml 
deployment.apps/elasticsearch created
configmap/elasticsearch-nginx created
$

执行 “oc get pod” 命令并确认其状态为 “Runnning”。如果还未达到 “Runnning” 状态,请重复执行 “oc get pod” 命令直到达到该状态为止。

$ oc get pod
NAME                             READY   STATUS    RESTARTS   AGE
elasticsearch-84cb95cc8c-c9v46   2/2     Running   0          108s
$ 

在这里,由于通过1个pod运行2个container部署,因此READY栏的输出为2/2(即2个container中有2个正在运行)。

执行4:验证连接到Elasticsearch服务。

使用oc run命令,在同一项目中启动一个一次性容器,并通过curl命令访问elastichsearch服务。如果一切正常,将从elastichsearch容器中收到响应。在此,我们已将nginx部署在elastichsearch之前,监听https连接,因此curl命令需要指定使用https进行访问。此外,由于服务器证书是自签证书,我们也需要加上-k选项。

$ oc run -it --rm --image=curlimages/curl curl   -- curl -k https://elasticsearch:9200
If you don't see a command prompt, try pressing enter.
{
  "name" : "elasticsearch-84cb95cc8c-zmc2t",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "3lfwkLlnShiD5AJeZWZefA",
  "version" : {
    "number" : "7.9.3",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "c4138e51121ef06a6404866cddc601906fe5c868",
    "build_date" : "2020-10-16T10:36:16.141335Z",
    "build_snapshot" : false,
    "lucene_version" : "8.6.2",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}
Session ended, resume using 'oc attach curl -c curl -i -t' command when the pod is running
pod "curl" deleted
$  

使用oc logs命令可以从nginx容器的日志中确认实际是否有访问到nginx。

$ oc get pod
NAME                             READY   STATUS    RESTARTS   AGE
elasticsearch-84cb95cc8c-zmc2t   2/2     Running   0          11m
$ oc logs elasticsearch-84cb95cc8c-zmc2t nginx-proxy | grep curl
10.217.0.69 - - [30/Jun/2022:15:15:45 +0000] "GET / HTTP/1.1" 200 559 "-" "curl/7.83.1-DEV"
$ 

而且,當從一次性容器進行訪問確認時,使用 curl 命令發送的請求若是 HTTP,則會返回錯誤。(HTTP 400)

$ oc run -it --rm --image=curlimages/curl curl   -- curl http://elasticsearch:9200
If you don't see a command prompt, try pressing enter.
<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
<hr><center>nginx/1.23.0</center>
</body>
</html>
Session ended, resume using 'oc attach curl -c curl -i -t' command when the pod is running
pod "curl" deleted
$ 

经过此确认,我们能够在elasticsarch容器前放置nginx容器,并使其像https代理一样运行。

以上

广告
将在 10 秒后关闭
bannerAds