kubernetesに入門してみる 2日目

ImagePullBackOffで起動しない解決編

バージョンをlatestにしていると常にdocker registryにpullしてしまうみたい。
ということでjibでイメージを作るときに適当にタグを付けてあげる

    jib {
        to {
            image = "net.orekyuu/" + project.name
            tags = ["0.0.1"] // とりあえず固定値で渡してみる
        }
        from {
            image = "openjdk:12"
        }
    }

docker-compose.yml側にも変更

version: '3.7'

services:
  hello-app:
    image: net.orekyuu/hello:0.0.1
    ports:
      - 8080:8080

デプロイしてみる!

D:\repos\spring-illust-service>docker stack deploy --orchestrator=kubernetes -c docker-compose.yml hello
Waiting for the stack to be stable and running...
hello-app: Ready                [pod status: 1/1 ready, 0/1 pending, 0/1 failed]

Stack hello is stable and running


D:\repos\spring-illust-service>kubectl get all
NAME                             READY   STATUS    RESTARTS   AGE
pod/hello-app-6f985844fb-n8vrb   1/1     Running   0          16s

NAME                          TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
service/hello-app             ClusterIP      None           <none>        55555/TCP        16s
service/hello-app-published   LoadBalancer   10.97.45.121   localhost     8080:31557/TCP   15s
service/kubernetes            ClusterIP      10.96.0.1      <none>        443/TCP          21h

NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/hello-app   1/1     1            1           16s

NAME                                   DESIRED   CURRENT   READY   AGE
replicaset.apps/hello-app-6f985844fb   1         1         1       16s

なんだか動いてそう…!
localhost:8080で動いてるはずなのでアクセス

f:id:orekyuu:20190911200429p:plain やったー!

replicateしてみる

hello appを増やしてみる

version: '3.7'

services:
  hello-app:
    image: net.orekyuu/hello:0.0.1
    ports:
      - 8080:8080
    deploy:
      replicas: 2

もっかいデプロイ!

D:\repos\spring-illust-service>docker stack deploy --orchestrator=kubernetes -c docker-compose.yml hello
Waiting for the stack to be stable and running...
hello-app: Ready                [pod status: 1/1 ready, 0/1 pending, 0/1 failed]

Stack hello is stable and running


D:\repos\spring-illust-service>docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
958fbfb96101        f61f158e7339        "java -cp /app/resou…"   3 seconds ago       Up 1 second                             k8s_hello-app_hello-app-6f985844fb-8qrlz_default_8ad9e77c-d484-11e9-99f8-0
0155da07b15_0
e9165ba15192        f61f158e7339        "java -cp /app/resou…"   3 minutes ago       Up 3 minutes                            k8s_hello-app_hello-app-6f985844fb-n8vrb_default_2ad820d9-d483-11e9-99f8-0
0155da07b15_1

ちゃんと2台になってる。面白い~!

Eurekaを入れる

Spring Cloudを触ってみたいモチベーションがあったのでまずはEurekaから入れてみる
新しいプロジェクトを作ってピャッっと書く。アプリケーションのコードはこんな感じ

project(":eureka") {
    dependencies {
        implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
        // ↓JDK9以降だと自分でJAXB周り入れておかないとJigsawの影響とかで起動できない…
        implementation 'javax.xml.bind:jaxb-api:+'
        implementation 'com.sun.xml.bind:jaxb-impl:+'
        implementation 'org.glassfish.jaxb:jaxb-runtime:+'
        implementation 'javax.activation:activation:+'
    }
}
@SpringBootApplication
@EnableEurekaServer
public class DiscoveryApplication {
    public static void main(String[] args) {
        SpringApplication.run(DiscoveryApplication.class, args);
    }
}
server:
  port: 8761
eureka:
  client:
    register-with-eureka: false
    fetch-registry: false

自分自身を登録しないようにregister-with-eurekaとかはfalseにしておくと良いらしい。って書いてあった
jibでビルドしてdocker-compose.ymlに追記してあげる

version: '3.7'

services:
  hello-app:
    image: net.orekyuu/hello:0.0.1
    ports:
      - 8080:8080
    deploy:
      replicas: 2
  eureka:
    image: net.orekyuu/eureka:0.0.1
    ports:
      - 8761:8761
    deploy:
      replicas: 1

localhost:8761にアクセスするとダッシュボードが見れる f:id:orekyuu:20190911211027p:plain

ちょっと寄り道してJAXB周りでエラー出た話

一発目はJAXB周りに気付かず起動しないなー?になっていた。
kubectl get allを打つとコンテナの状態が見れるので叩いてみる。

D:\repos\spring-illust-service>kubectl get all
NAME                             READY   STATUS    RESTARTS   AGE
pod/eureka-586c7cbc48-mrb2h      0/1     Error     3          93s
pod/hello-app-6f985844fb-4stpb   1/1     Running   0          93s
pod/hello-app-6f985844fb-wl4zn   1/1     Running   0          93s

NAME                          TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
service/eureka                ClusterIP      None           <none>        55555/TCP        93s
service/eureka-published      LoadBalancer   10.109.74.59   localhost     8761:30876/TCP   92s
service/hello-app             ClusterIP      None           <none>        55555/TCP        92s
service/hello-app-published   LoadBalancer   10.96.5.72     localhost     8080:30280/TCP   93s
service/kubernetes            ClusterIP      10.96.0.1      <none>        443/TCP          22h

NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/eureka      0/1     1            0           93s
deployment.apps/hello-app   2/2     2            2           93s

NAME                                   DESIRED   CURRENT   READY   AGE
replicaset.apps/eureka-586c7cbc48      1         1         0       93s
replicaset.apps/hello-app-6f985844fb   2         2         2       93s

eurekaがエラーで再起動くりかえしてるぽい。原因は外からじゃわからないのでログをみたい。
kubectl logs [pod名]でログが取れるので打ってみる

D:\repos\spring-illust-service>kubectl logs pod/eureka-586c7cbc48-mrb2h
2019-09-11 11:52:44.502  INFO 1 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.auto
configure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$8ccca102] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.8.RELEASE)

2019-09-11 11:52:44.703  INFO 1 --- [           main] net.orekyuu.eureka.DiscoveryApplication  : No active profile set, falling back to default profiles: default
2019-09-11 11:52:45.492  WARN 1 --- [           main] o.s.boot.actuate.endpoint.EndpointId     : Endpoint ID 'service-registry' contains invalid characters, please migrate to a valid format.
2019-09-11 11:52:45.840  INFO 1 --- [           main] o.s.cloud.context.scope.GenericScope     : BeanFactory id=10faa10b-835d-3f55-bd87-0a6398f3b9c7
...
java.lang.NoClassDefFoundError: com/sun/istack/FinalArrayList
        at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:249) ~[jaxb-impl-2.4.0-b180830.0438.jar:2.4.0-b180830.0438]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:567) ~[na:na]
        at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:208) ~[jaxb-api-2.4.0-b180830.0359.jar:2.3.0]
        at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:166) ~[jaxb-api-2.4.0-b180830.0359.jar:2.3.0]

みたいな感じでjaxb周りでコケてることがわかった。

hello-appにeureka-clientを入れる

eureka-clientを入れてeurekaに登録するようにする

project(":hello") {
    dependencies {
        implementation 'org.springframework.boot:spring-boot-starter-web'
        // ↓新しく追加した
        implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
    }
}
spring:
  application:
    name: hello-app
eureka:
  client:
    service-url:
      defaultZone: ${EUREKA_URI:http://localhost:8761/eureka}

登録する先は環境変数で渡せるようにしておく。イメージ作り直すのいやだしね。

docker-composeを書いてあげる

version: '3.7'

services:
  hello-app:
    image: net.orekyuu/hello:0.0.3
    ports:
      - 8080:8080
    deploy:
      replicas: 2
    environment:
      EUREKA_URI: http://10.104.224.80:8761/eureka
  eureka:
    image: net.orekyuu/eureka:0.0.4
    ports:[f:id:orekyuu:20190911213036p:plain]
      - 8761:8761
    deploy:
      replicas: 1

ipアドレスはkubectl get allを叩いてservice/eureka-publishedのIPを入れた。いや、良くないのはわかっているけどとりあえず動かして楽しくなりたかった…!
あとで正しい方法は調べるとしてこれでdeployしてみる。 f:id:orekyuu:20190911213036p:plain ちゃんとインスタンスが2つ登録されていることが確認できたので満足!
明日はAPI Gatewayとか試してみよ~