[k8s]args指令案例-徹底理解docker entrypoint

需求:

搞個鏡像,可以運行java -jar xxx.jar包,xxx.jar包名稱要用參數傳

  • 思路1: 打對應運行jar包的jdk的image.
  • 思路2: 打通用jdk

1, 運行指定jar的指定版的jdk

  • k8s運行該image遇到的問題

    • kubectl create -f sms.yaml時報
  rpc error: code = 2 desc = failed to start container "cffbbc3d295f7b5a8d497c8147f7222636b51647387cda491a89d292437c7e47": Error response from daemon: {"message":"invalid header field value \"oci runtime error: container_linux.go:247: starting container process caused \\\"exec: \\\\\\\"/tmp/sms-xx.jar\\\\\\\": permission denied\\\"\\n\""} 
  • 等了一會pod奔潰了,報錯
  failed to open log file "/var/log/pods/6533426e-aeec-11e7-b1c6-025622f1d9fa/sms-test_3.log": open /var/log/pods/6533426e-aeec-11e7-b1c6-025622f1d9fa/sms-test_3.log: no such file or directory 

gg了好一陣,沒發現方法解決

  • 這是我的yaml
sms.yaml

apiVersion: v1
kind: Pod
metadata:
  name: sms-test
  labels:
    app: sms-test
spec:
  containers:    
  - name: sms-test
    image: sms
    imagePullPolicy: IfNotPresent
    command: ["/tmp/sms-xxx.jar"]
    volumeMounts:
    - mountPath: /tmp
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      path: /tmp

報錯問題見上!


  • 但是我這樣啓鏡像是正常的
#vm的tmp下放xxx.jar,掛到容器裏
docker run -v /tmp:/tmp -itd sms '/tmp/sms-xxx.jar'

我一般處理容器化業務思路:

0,物理vm先打通該服務. 1. 打docker鏡像.docker run先跑起來. 2.寫yaml改造成k8s

  • 我安裝思路1定義運行jar包的jdk:的dockerfile
Dockerfile


FROM airdock/base:jessie

RUN mkdir -p /srv/java/
# Add java dynamic memory script
COPY java-dynamic-memory-opts /srv/java/

# Install Oracle JDK 8u25
RUN cd /tmp && \
    curl -L -O "http://xxx/jdk-8u25-linux-x64.gz" && \
    tar xf jdk-8u25-linux-x64.gz -C /srv/java && \
    rm -f jdk-8u25-linux-x64.gz && \
    ln -s /srv/java/jdk* /srv/java/jdk && \
    ln -s /srv/java/jdk /srv/java/jvm && \
    chown -R java:java /srv/java && \
    /root/post-install

# Define commonly used JAVA_HOME variable
# Add /srv/java and jdk on PATH variable
ENV JAVA_HOME=/srv/java/jdk \
    PATH=${PATH}:/srv/java/jdk/bin:/srv/java

COPY docker-entrypoint.sh /bin/

ENTRYPOINT ["docker-entrypoint.sh"]
docker-entrypoint.sh

#!/bin/bash
java -jar $1

嗯哼? 沒毛病.

解決k8s運行定製jdk環境的問題:

方法: yaml裏command換args指令即可.

sms.yaml

...
spec:
  containers:    
  - name: sms-test
    image: sms
    imagePullPolicy: IfNotPresent
    args: ["/tmp/sms-xxx.jar"]
...
  • 剖析
docker run -v /tmp:/tmp -itd sms '/tmp/sms-xxx.jar'
                                                         這裏args,而非commands

2, 使jdk環境通用化

想想爲了運行一個jar包,定義個運行jar的jdk環境,有點得不償失.思路:爲了通用性,搞個指定版本jdk image,管他運行什麼呢.

Dockerfile

FROM airdock/base:jessie

RUN mkdir -p /srv/java/
# Add java dynamic memory script
COPY java-dynamic-memory-opts /srv/java/

# timezone 這裏把時區改掉
COPY localtime /etc/localtime
# Install Oracle JDK 8u25
RUN cd /tmp && \
    curl -L -O "http://xxx/jdk-8u25-linux-x64.gz" && \
    tar xf jdk-8u25-linux-x64.gz -C /srv/java && \
    rm -f jdk-8u25-linux-x64.gz && \
    ln -s /srv/java/jdk* /srv/java/jdk && \
    ln -s /srv/java/jdk /srv/java/jvm && \
    chown -R java:java /srv/java && \
    /root/post-install

# Define commonly used JAVA_HOME variable
# Add /srv/java and jdk on PATH variable
ENV JAVA_HOME=/srv/java/jdk \
    PATH=${PATH}:/srv/java/jdk/bin:/srv/java
apiVersion: v1
kind: Pod
metadata:
  name: sms-test
  labels:
    app: sms-test
spec:
  containers:    
  - name: sms-test
    image: jdk8u25-ori
    imagePullPolicy: IfNotPresent
    command: ["java","-jar","/tmp/sms-xxx.jar"]
    volumeMounts:
    - mountPath: /tmp
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      path: /data

經過觀察jar包運行良好.
可見理解k8s yaml指令還是有點必要的.不然天天閒的蛋疼,沒事幹. 人生最大的敵人是無聊.

徹底理解entrypiont-命令行揉搓擠捏

指定entrypiont

  • 錯誤的姿勢
 docker run -itd -v /tmp/:/tmp/ jdk-ori 'java -jar /tmp/sms.jar'
  • 正確的姿勢1
 docker run -itd -v /tmp/:/tmp/ jdk-ori java -jar '/tmp/sms.jar'
  • 正確姿勢2:
docker run -it -itd -v /tmp/:/tmp/ --entrypoint /srv/java/jdk/bin/java jdk-ori -jar /tmp/sms.jar


 --entrypoint "/srv/java/jdk/bin/java -jar"  這樣是不支持的, 這個傳參方式不能加參數 ,而dockerfile裏則可以
  • 正確姿勢3: 掛腳本方式
$ cat /tmp/entry.sh
#!/bin/bash
java -jar $1

docker run -it --rm -v /tmp/:/tmp/ --entrypoint "/tmp/entry.sh" jdk-ori /tmp/sms.jar

也可以指定這些:
https://docs.docker.com/engine/reference/run/#entrypoint-default-command-to-execute-at-runtime

CMD (Default Command or Options)
ENTRYPOINT (Default Command to Execute at Runtime)
EXPOSE (Incoming Ports)
ENV (Environment Variables)
HEALTHCHECK
VOLUME (Shared Filesystems)
USER
WORKDIR

如何在k8s裏指定docker run -w 的workdir

思路: 可以通過env方式

[root@k8s-master01 ma]# cat centos.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: my-centos
  labels:
    app: centos
spec:
  containers:
  - name: my-centos
    image: centos:6.8
    imagePullPolicy: IfNotPresent
    command: ["top","-b"]
    env:
      - name: PWD
        value: "/tmp"

一個計時的pod

apiVersion: v1
kind: Pod
metadata:
  name: counter
spec:
  containers:
  - name: count
    image: busybox
    args: [/bin/sh, -c,
            'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done']

參考: https://www.ibm.com/developerworks/community/blogs/132cfa78-44b0-4376-85d0-d3096cd30d3f/entry/RUN_vs_CMD_vs_ENTRYPOINT_%E6%AF%8F%E5%A4%A95%E5%88%86%E9%92%9F%E7%8E%A9%E8%BD%AC_Docker_%E5%AE%B9%E5%99%A8%E6%8A%80%E6%9C%AF_17?lang=en

https://k8smeetup.github.io/docs/concepts/cluster-administration/logging/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章